From f492913626d2c45ed09b1434a201e65d80853ab7 Mon Sep 17 00:00:00 2001 From: abhishek ranjan Date: Wed, 5 Oct 2022 01:04:19 +0530 Subject: [PATCH] added some of the question of dynamic problems --- .../LC_2407_LongestIncreasingSubsequence2.cpp | 64 +++++++++++++++++++ .../LC_42_TrappingRainWater.cpp | 27 ++++++++ Dynamic Programming/LC_5LongestPalindrome.cpp | 43 +++++++++++++ Dynamic Programming/LC_72EditDistance.cpp | 64 +++++++++++++++++++ Dynamic Programming/LC_87ScrambleString.cpp | 58 +++++++++++++++++ 5 files changed, 256 insertions(+) create mode 100644 Dynamic Programming/LC_2407_LongestIncreasingSubsequence2.cpp create mode 100644 Dynamic Programming/LC_42_TrappingRainWater.cpp create mode 100644 Dynamic Programming/LC_5LongestPalindrome.cpp create mode 100644 Dynamic Programming/LC_72EditDistance.cpp create mode 100644 Dynamic Programming/LC_87ScrambleString.cpp diff --git a/Dynamic Programming/LC_2407_LongestIncreasingSubsequence2.cpp b/Dynamic Programming/LC_2407_LongestIncreasingSubsequence2.cpp new file mode 100644 index 0000000..53ad96a --- /dev/null +++ b/Dynamic Programming/LC_2407_LongestIncreasingSubsequence2.cpp @@ -0,0 +1,64 @@ +#include +#include +using namespace std; +class MaxSegmentTree +{ +public: + int n; + vector tree; + MaxSegmentTree(int n_) : n(n_) + { + int size = (int)(ceil(log2(n))); + size = (2 * pow(2, size)) - 1; + tree = vector(size); + } + + int max_value() { return tree[0]; } + + int query(int l, int r) { return query_util(0, l, r, 0, n - 1); } + + int query_util(int i, int qL, int qR, int l, int r) + { + if (l >= qL && r <= qR) + return tree[i]; + if (l > qR || r < qL) + return INT_MIN; + + int m = (l + r) / 2; + return max(query_util(2 * i + 1, qL, qR, l, m), query_util(2 * i + 2, qL, qR, m + 1, r)); + } + + void update(int i, int val) { update_util(0, 0, n - 1, i, val); } + void update_util(int i, int l, int r, int pos, int val) + { + if (pos < l || pos > r) + return; + if (l == r) + { + tree[i] = max(val, tree[i]); + return; + } + + int m = (l + r) / 2; + update_util(2 * i + 1, l, m, pos, val); + update_util(2 * i + 2, m + 1, r, pos, val); + tree[i] = max(tree[2 * i + 1], tree[2 * i + 2]); + } +}; + +class Solution +{ +public: + int lengthOfLIS(vector &nums, int k) + { + MaxSegmentTree tree(1e5 + 1); + for (int i : nums) + { + int lower = max(0, i - k); + int cur = 1 + tree.query(lower, i - 1); + tree.update(i, cur); + } + + return tree.max_value(); + } +}; \ No newline at end of file diff --git a/Dynamic Programming/LC_42_TrappingRainWater.cpp b/Dynamic Programming/LC_42_TrappingRainWater.cpp new file mode 100644 index 0000000..7b1ae77 --- /dev/null +++ b/Dynamic Programming/LC_42_TrappingRainWater.cpp @@ -0,0 +1,27 @@ + +#include +using namespace std; +class Solution +{ +public: + int trap(vector &height) + { + int n = height.size(), ans = 0; + vector left(n); + // left will store max left height till ith index + left[0] = height[0]; + for (int i = 1; i < n; i++) + left[i] = max(left[i - 1], height[i]); + // right will store max right height till ith index + vector right(n); + right[n - 1] = height[n - 1]; + + for (int i = n - 2; i >= 0; i--) + right[i] = max(right[i + 1], height[i]); + // calculating trapped water + for (int i = 1; i < n - 1; i++) + ans += min(left[i], right[i]) - height[i]; + + return ans; + } +}; \ No newline at end of file diff --git a/Dynamic Programming/LC_5LongestPalindrome.cpp b/Dynamic Programming/LC_5LongestPalindrome.cpp new file mode 100644 index 0000000..b25876d --- /dev/null +++ b/Dynamic Programming/LC_5LongestPalindrome.cpp @@ -0,0 +1,43 @@ +#include +#include +using namespace std; + +string longestPalindrome(string s) +{ + if (s.size() == 0) + return ""; + int n = s.size(); + int table[n][n]; + memset(table, -1, sizeof(table)); // Initializing table with -1 + for (int i = 0; i < n; ++i) + table[i][i] = 1; // Filling up the table + int maxLen = 1; + int start = 0; + for (int i = 0; i < n - 1; ++i) + { // checking for substring of length 2. + if (s[i] == s[i + 1]) + { + table[i][i + 1] = 1; + start = i; // Updating the start + maxLen = 2; + } + } + for (int k = 3; k <= n; k++) + { // Checking for length greater than 2 and k is length of substring + for (int i = 0; i < n - k + 1; i++) + { + int j = i + k - 1; // Initializing the end Index i.e j = i + k - 1 + if (table[i + 1][j - 1] == 1 && s[i] == s[j]) + { // Checking for the conditions i.e checking for sub-string from ith index to jth index. + table[i][j] = 1; + if (k > maxLen) + { // Updating the maxLen + start = i; // Updating the start + maxLen = k; + } + } + } + } + return s.substr(start, maxLen); +} + diff --git a/Dynamic Programming/LC_72EditDistance.cpp b/Dynamic Programming/LC_72EditDistance.cpp new file mode 100644 index 0000000..82db109 --- /dev/null +++ b/Dynamic Programming/LC_72EditDistance.cpp @@ -0,0 +1,64 @@ + +#include +using namespace std; + +string w1, w2; + +int dp[505][505]; + +int solve(int i, int j) +{ + int ans = INT_MAX; + + if (i == w1.length() && j < w2.length()) + { + // use insert op + return dp[i][j] = min(ans, 1 + solve(i, j + 1)); + } + + if (j == w2.length() && i < w1.length()) + { + // use delete op + return dp[i][j] = min(ans, 1 + solve(i + 1, j)); + } + + if (i == w1.length() && j == w2.length()) + { + return dp[i][j] = 0; + } + + if (dp[i][j] != INT_MAX) + { + return dp[i][j]; + } + + if (w1[i] == w2[j]) + { + ans = min(ans, solve(i + 1, j + 1)); + } + else + { + // insert + ans = min(ans, 1 + solve(i, j + 1)); + // delete + ans = min(ans, 1 + solve(i + 1, j)); + // replace + ans = min(ans, 1 + solve(i + 1, j + 1)); + } + return dp[i][j] = ans; +} + +int minDistance(string word1, string word2) +{ + // O(N^2) + w1 = word1; + w2 = word2; + for (int i = 0; i < 505; i++) + { + for (int j = 0; j < 505; j++) + { + dp[i][j] = INT_MAX; + } + } + return solve(0, 0); +} \ No newline at end of file diff --git a/Dynamic Programming/LC_87ScrambleString.cpp b/Dynamic Programming/LC_87ScrambleString.cpp new file mode 100644 index 0000000..af6f8be --- /dev/null +++ b/Dynamic Programming/LC_87ScrambleString.cpp @@ -0,0 +1,58 @@ + +// So we have 2 strings s1 and s2 and we need to check if they are scrambled strings are not +// For that we can follow the MCM pattern of dividing the string into 2 parts at every possible point +// So we can do 2 possible things at a point +// 1. leave the string as it is +// 2. swap it! +// Let us assume you are at index 1 and you want to leave the string as it is then it would be true if and only if (0,1) of s1 == (0,1) of s2 (AND) (1,n) of s1 == (1,n) of s2 +// Now for swap case let us assume we are at index 1 and now we will check if (0,1) of s1 == (n-1,1) of s2 (AND) (1,n) of s1 == (0,n-1) of s2 +// (Here 's1==s2' doesn't mean we are comparing both the string it represent whether s1 and s2 are scrambled strings or not) + +#include +using namespace std; +class Solution +{ +public: + bool rec(string s1, string s2, unordered_map &um) + { + int n = s1.size(); + if (s1 == s2) + { + return 1; + } + if (n == 1) + { + return 0; + } + int flag = 0; + if (um.find(s1 + " " + s2) != um.end()) + { + return um[s1 + " " + s2]; + } + for (int k = 1; k < n; k++) + { + if (rec(s1.substr(0, k), s2.substr(0, k), um) && rec(s1.substr(k), s2.substr(k), um)) + { + flag = 1; + } + if (flag == 1) + { + return true; + } + if (rec(s1.substr(0, k), s2.substr(n - k), um) && rec(s1.substr(k), s2.substr(0, n - k), um)) + { + flag = 1; + } + if (flag == 1) + { + return true; + } + } + return um[s1 + " " + s2] = flag; + } + bool isScramble(string s1, string s2) + { + unordered_map um; + return rec(s1, s2, um); + } +}; \ No newline at end of file