From 8a5b995b9f886b4db57662ccb8d1e4b533cf3df9 Mon Sep 17 00:00:00 2001 From: Rachit Jain Date: Fri, 26 Jun 2020 21:24:21 +0530 Subject: [PATCH 01/20] added a shorter template for C++ --- Library/Miscellanious/template-short.cpp | 40 ++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 Library/Miscellanious/template-short.cpp diff --git a/Library/Miscellanious/template-short.cpp b/Library/Miscellanious/template-short.cpp new file mode 100644 index 0000000..aa4571c --- /dev/null +++ b/Library/Miscellanious/template-short.cpp @@ -0,0 +1,40 @@ +#include +using namespace std; +#define gc getchar_unlocked +#define fo(i,n) for(i=0;in;k Trie::autoComplete(const string &prefix) { + +} +bool Trie::isPresent(const string &word) { + +} From d6096866096fe05683c4c3f24186b3e7edf4c479 Mon Sep 17 00:00:00 2001 From: Rachit Jain Date: Tue, 11 May 2021 01:19:25 +0530 Subject: [PATCH 11/20] implemented a complex trie data structure --- Library/Tree/trie.cpp | 100 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 95 insertions(+), 5 deletions(-) diff --git a/Library/Tree/trie.cpp b/Library/Tree/trie.cpp index a5bfe03..ba7d013 100644 --- a/Library/Tree/trie.cpp +++ b/Library/Tree/trie.cpp @@ -6,18 +6,35 @@ using namespace std; class Trie { - map keys = {}; - int traversed = 0; - bool isLeaf = 0; + map m_keys = {}; // what are the next avail chars in trie node + int m_traversed = 0; // how many words in trie are proper prefix + bool m_isLeaf = 0; // is this trie node a leaf node i.e a word ends here + int m_depth = 0; // depth of trie node + public: + Trie() = default; + Trie(int depth): m_depth(depth) {} + int getDepth() { return m_depth; } + bool isKeyPresent(const char &c) { return m_keys.find(c) != m_keys.end(); } + bool isLeaf() { return m_isLeaf; } + void setLeaf() { m_isLeaf = 1; } void add(const string &word); int matchLength(const string &prefix); // returns the length of max prefix that exists in trie + vector getAllWords(); vector autoComplete(const string &prefix); bool isPresent(const string &word); + void addKey(const char &c); + Trie *to(const char &c); }; template void assertVectors(const vector& lhs, const vector& rhs) { + // for(auto e: lhs) + // cout << e << " "; + // cout << endl; + // for(auto e: rhs) + // cout << e << " "; + // cout << endl; assert(lhs.size() == rhs.size()); for (int i = 0; i < lhs.size(); i++) { @@ -36,9 +53,11 @@ int main() { t.add(w); } + assertVectors(t.autoComplete(""), words); assertVectors(t.autoComplete("Ra"), {"Rachit", "Rachit1", "Ramesh"}); assertVectors(t.autoComplete("Rachit"), {"Rachit", "Rachit1"}); assertVectors(t.autoComplete("Rachit1"), {"Rachit1"}); + assertVectors(t.autoComplete("Rachit12"), {}); assert(t.isPresent("")); assert(!t.isPresent("Racht")); @@ -52,19 +71,90 @@ int main() { return 0; } +// add the given char to current Trie node +void Trie::addKey(const char& c) { + if(!isKeyPresent(c)) { + m_keys[c] = new Trie(m_depth + 1); + } + m_traversed++; +} + +Trie* Trie::to(const char& c) { + if(!isKeyPresent(c)) { + return NULL; + } + return m_keys[c]; +} +// add the word to trie, duplicates are ignored void Trie::add(const string &word) { - + Trie *cur = this; + for (char c: word) + { + cur->addKey(c); + cur = cur->to(c); + } + cur->setLeaf(); } // returns the length of max prefix that exists in trie int Trie::matchLength(const string &prefix) { + Trie *cur = this; + int match = 0; + for (char c: prefix) { + if (cur->isKeyPresent(c)) { + match++; + cur = cur->to(c); + } + else { + return match; + } + } + return match; +} +vector Trie::getAllWords() { + vector ans = {}; + for (auto it: m_keys) { + char c = it.first; + Trie *t = it.second; + if (t->isLeaf()) { + ans.push_back(string("") + c); + } + for (auto word: t->getAllWords()) { + ans.push_back(c + word); + } + } + + return ans; } vector Trie::autoComplete(const string &prefix) { + if (!isPresent(prefix)) { + return {}; + } + vector ans = {}; + + Trie *cur = this; + for (char c: prefix) { + if (cur->isKeyPresent(c)) { + cur = cur->to(c); + } + else { + break; + } + } + if (cur->isLeaf()) { + ans.push_back(prefix); + } + + for (auto restWord: cur->getAllWords()) { + ans.push_back(prefix + restWord); + } + return ans; } -bool Trie::isPresent(const string &word) { +bool Trie::isPresent(const string &word) { + return matchLength(word) == word.size(); } From 659d45b9019d576cd013b4bbf4ba2e66fab51713 Mon Sep 17 00:00:00 2001 From: Rachit Jain Date: Sat, 22 May 2021 23:24:23 +0530 Subject: [PATCH 12/20] GRAPH_LIVE_YOUTUBE - 3 problems https://www.youtube.com/watch?v=4B0M0biIa3E --- LeetCode/765.couples-holding-hands.cpp | 69 +++++++++++++++++++ .../797.all-paths-from-source-to-target.cpp | 51 ++++++++++++++ LeetCode/997.find-the-town-judge.cpp | 26 +++++++ 3 files changed, 146 insertions(+) create mode 100644 LeetCode/765.couples-holding-hands.cpp create mode 100644 LeetCode/797.all-paths-from-source-to-target.cpp create mode 100644 LeetCode/997.find-the-town-judge.cpp diff --git a/LeetCode/765.couples-holding-hands.cpp b/LeetCode/765.couples-holding-hands.cpp new file mode 100644 index 0000000..ec357cf --- /dev/null +++ b/LeetCode/765.couples-holding-hands.cpp @@ -0,0 +1,69 @@ +const int N = 70; +set g[N]; +bool vis[N]; + +void fill_cluster_size(int u, int &cluster_size) { + vis[u] = 1; + // cout << "dfs::at couple " << u << endl; + cluster_size++; + for(int v: g[u]) { + if(!vis[v]) { + fill_cluster_size(v, cluster_size); + } + } +} + +int get_couple_id(int person) { + return person / 2; +} + + +class Solution { +public: + int minSwapsCouples(vector& row) { + int n = row.size() / 2; + // normalizing the seating arrangement in terms of couple ids + for(int &x: row) x = get_couple_id(x); + + for(int i = 0; i < n; i++) { + g[i].clear(); + vis[i] = 0; + } + + for(int i = 0; i < row.size(); i += 2) { + int c1 = row[i], c2 = row[i+1]; + if( c1 == c2 ) continue; + g[c1].insert(c2); + g[c2].insert(c1); + // cout << i << " adding edge in couple " << c1 << " " << c2 << endl; + } + + int ans = 0; + for(int i = 0; i < n; i++) { + if(!vis[i]) { + int cluster_size = 0; + fill_cluster_size(i, cluster_size); + ans += cluster_size - 1; + } + } + return ans; + } +}; +/* + 0,3,1,2 -> 0,1,3,2 + easy notation: 0,1,0,1 + - Find a swap that can make two couples happy. + - +(0, 1) --- 1st couple --- couple id = 0 +(2, 3) --- 2nd couple --- couple id = 1 +(4, 5) -- 3rd couple --- couple id = 2 + 0,3,5,2,1,4 --> 0,1,2,1,0,2 + + 0---1---2 + \______/ + +x----y <--- 1 swap +x----y----z <--- 2 swaps + +C couples --- C-1 swaps +*/ diff --git a/LeetCode/797.all-paths-from-source-to-target.cpp b/LeetCode/797.all-paths-from-source-to-target.cpp new file mode 100644 index 0000000..d7b9868 --- /dev/null +++ b/LeetCode/797.all-paths-from-source-to-target.cpp @@ -0,0 +1,51 @@ +const int N = 20; +vector g[N]; +using path = vector; +set get_all_paths(int src, int tar) { + // cout << src << endl; + if(src == tar) return { {tar} }; + set ans = {}; + for(int v: g[src]) { + auto rem_paths = get_all_paths(v, tar); + for (path p: rem_paths) { + p.push_back(src); + ans.insert(p); + } + } + return ans; +} + + +class Solution { + +public: + + vector> allPathsSourceTarget(vector>& graph) { + // paths from 0 to 4 + // iterate on children v of 0 + // find paths from child v to 4 + // [0,1,3,4] + int n = graph.size(); + + if(n == 0) return {}; + for(int i = 0; i < n; i++) g[i].clear(); + + for(int i = 0; i < n; i++) { + for(int v: graph[i]) { + g[i].push_back(v); + } + } + + vector ans = {}; + set paths = get_all_paths(0, n-1); + + + // O(# of paths * avg_size of path) + for(auto p: paths) { + reverse(p.begin(), p.end()); + ans.push_back(p); + } + + return ans; + } +}; diff --git a/LeetCode/997.find-the-town-judge.cpp b/LeetCode/997.find-the-town-judge.cpp new file mode 100644 index 0000000..a6e9c8c --- /dev/null +++ b/LeetCode/997.find-the-town-judge.cpp @@ -0,0 +1,26 @@ +class Solution { +public: + int findJudge(int n, vector>& trust) { + vector followers(n+1, 0); // 1 based indexing + vector does_follow(n+1, 0); + + map followers, does_follow; // O(logN) + + for(auto edge: trust) { + int u = edge[0], v = edge[1]; + // person u trusts v + followers[v]++; // O(1) v/s in maps O(logN) --> O(1) + does_follow[u] = 1; + } + + vector final_candidates = {}; + for(int i = 1; i <= n; i++) { + if(followers[i] == n-1 && does_follow[i] == 0) { + final_candidates.push_back(i); + } + } + + if(final_candidates.size() != 1) return -1; + return final_candidates[0]; + } +}; From efcc86e6628d63725b1ddef5d8655fe7026f1a79 Mon Sep 17 00:00:00 2001 From: Rachit Jain Date: Mon, 24 May 2021 21:51:41 +0530 Subject: [PATCH 13/20] LIVE_YOUTUBE - Developer Bhaiya - 3 problems https://youtu.be/_I8q2nFu47I First Problem: https://leetcode.com/problems/best-time-to-buy-and-sell-stock Second problem: https://leetcode.com/problems/stone-game/ Third problem: https://leetcode.com/problems/jump-game/ https://www.youtube.com/watch?v=4KAQ6UViDoE +1 -1 trick: https://www.youtube.com/watch?v=ERAHSoAk2Yo --- .../121.best-time-to-buy-and-sell-stock.cpp | 26 ++++++++ LeetCode/55.jump-game.cpp | 30 +++++++++ LeetCode/877.stone-game.cpp | 63 +++++++++++++++++++ 3 files changed, 119 insertions(+) create mode 100644 LeetCode/121.best-time-to-buy-and-sell-stock.cpp create mode 100644 LeetCode/55.jump-game.cpp create mode 100644 LeetCode/877.stone-game.cpp diff --git a/LeetCode/121.best-time-to-buy-and-sell-stock.cpp b/LeetCode/121.best-time-to-buy-and-sell-stock.cpp new file mode 100644 index 0000000..ebd217b --- /dev/null +++ b/LeetCode/121.best-time-to-buy-and-sell-stock.cpp @@ -0,0 +1,26 @@ +class Solution { +public: + int maxProfit(vector& prices) { + int n = prices.size(); + int ans = 0, suff_max = prices.back(); + for(int i = n-2; i >= 0; i--) { + ans = max(ans, suff_max - prices[i]); + suff_max = max(suff_max, prices[i]); + /* + for(int j = i+1; j < n; j++) { + ans = max(ans, prices[j] - prices[i]); + } + */ + } + return ans; + } +}; +/* + <---100---> +_ _ _ 120 _ _ _ _ _ _ + i + + max = 100 + */ + + diff --git a/LeetCode/55.jump-game.cpp b/LeetCode/55.jump-game.cpp new file mode 100644 index 0000000..22c9ef7 --- /dev/null +++ b/LeetCode/55.jump-game.cpp @@ -0,0 +1,30 @@ +class Solution { +public: + bool canJump(vector& nums) { + int n = nums.size(); + vector allowed(n, 0); // O(n) extra space + allowed[0] = 1; + for (int i = 0; i < n; i++) { + if (allowed[i]) { + for(int j = min(n-1, i+nums[i]); j >= i+1; j--) { + if(allowed[j]) break; + allowed[j] = 1; + } + } + } + return allowed[n-1]; + } +}; + +/* +_ _ _ 7 _ _ 1 1 1 1 1 _ + i x x x x x x x + +if i is allowerd and 100 + i+1,i+2,...,i+100 <-- allowed + +whether n-1 is allowed <-- true / false + + */ + + diff --git a/LeetCode/877.stone-game.cpp b/LeetCode/877.stone-game.cpp new file mode 100644 index 0000000..2374848 --- /dev/null +++ b/LeetCode/877.stone-game.cpp @@ -0,0 +1,63 @@ +#define deb(x1, x2, x3) cout << #x1 << "=" << x1 << " " << #x2 << "=" << x2 << " "<< #x3 << "=" << x3 << endl; + +class Solution { +public: + bool stoneGame(vector& piles) { + int n = piles.size(); + // dp[i][j] = max profit for first player when the game is at state [i..j] + vector> dp(n, vector(n, 0)); + for(int i = 0; i < n; i++) { + dp[i][i] = piles[i]; // 1 size subarrays have been computed + // if(i+1 < n) { + // dp[i][i+1] = abs(piles[i] - piles[i+1]); // subarrays of size 2 + // } + } + for(int len = 2; len <= n; len++) { + for(int i = 0; i < n; i++) { + int j = i + len - 1; + if(j >= n) continue; + // i .. j + // take the Lth stone + int choice1 = piles[i] - dp[i+1][j]; + + // take the Rth stone + int choice2 = piles[j] - dp[i][j-1]; + dp[i][j] = max(choice1, choice2); + // cout << i << " " << j << " " << dp[i][j] << endl; + // deb(i, j, dp[i][j]); + } + } + + + return dp[0][n-1] > 0; + } +}; + +/* +5, 3, 4, 5 -> 3,4,5 -> 3,4 -> 3 + + 5 + <---------------------->17 ==> 17 - 5 = 12 + 23,....................,17 + 23<----------------------> ===> 23-7 = 16 + 7 + + +state = [L, R] => by how much quantity the first player wins + + +[0, n-1] => +ve => first player can win -> true +[0, n-1] => -ve => first player cant win -> false + +// take the Lth stone +choice1 = piles[L] - win(L+1, R) + +// take the Rth stone +choice2 = piles[R] - win(L, R-1) + +win(L, R) = max(choice1, choice2); + +return win(0, n-1) > 0 + +*/ + From 26ba875da4a66e9136a03631f88cf546e8e3e61e Mon Sep 17 00:00:00 2001 From: Rachit Jain Date: Tue, 25 May 2021 22:45:41 +0530 Subject: [PATCH 14/20] LIVE_YOUTUBE - Developer Bhaiya - 2 problems, 1 script typing test --- LeetCode/45.jump-game2.cpp | 35 ++++++++++++++++++++++++++++++++++ LeetCode/841.keys-and-room.cpp | 33 ++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 LeetCode/45.jump-game2.cpp create mode 100644 LeetCode/841.keys-and-room.cpp diff --git a/LeetCode/45.jump-game2.cpp b/LeetCode/45.jump-game2.cpp new file mode 100644 index 0000000..0a2bdeb --- /dev/null +++ b/LeetCode/45.jump-game2.cpp @@ -0,0 +1,35 @@ +ass Solution { +public: + int jump(vector& nums) { + int n = nums.size(); + vector dp(n, INT_MAX - 1); + // dp[i] = min steps to reach the end of array if we are at ith index + dp[n-1] = 0; + for(int i = n-2; i >= 0; i--) { + for(int j = i+1; j <= i+nums[i]; j++) { + if(j >= n) break; + dp[i] = min(dp[i], 1 + dp[j]); + } + } + + return dp[0]; + } +}; + +/* +Find: min steps to reach the end of array + +Given: i -> we can jump a length of nums[i] +0 index + +_ _ _ _ 7 _ _ _ _ _ _ _ _ _ + i x x x x x x x + +dp[i] = min steps to reach the end of array if we are at ith index + +for(j=i+1; j<=i+7; j++) { + dp[i] = min(dp[i], 1 + dp[j]); +} + +return dp[0] +*/ diff --git a/LeetCode/841.keys-and-room.cpp b/LeetCode/841.keys-and-room.cpp new file mode 100644 index 0000000..8ed1768 --- /dev/null +++ b/LeetCode/841.keys-and-room.cpp @@ -0,0 +1,33 @@ +class Solution { +public: + bool canVisitAllRooms(vector>& rooms) { + int n = rooms.size(); + vector vis(n, 0); + + queue q; + q.push(0); + vis[0] = 1; + while(!q.empty()) { + int cur = q.front(); + q.pop(); + for(int child: rooms[cur]) { + if (!vis[child]) { + vis[child] = 1; + q.push(child); + } + } + } + for(int i = 0; i < n; i++) { + if(!vis[i]) return 0; + } + return 1; + } +}; + +/* +Input: [[1,3],[3,0,1],[2],[0]] +0 --> 1 +| +| +3 +*/ From 7147d16c7dcc09ab373131281c6e71f64c14eb85 Mon Sep 17 00:00:00 2001 From: Rachit Jain <32428330+rachitiitr@users.noreply.github.com> Date: Wed, 26 May 2021 11:39:23 +0530 Subject: [PATCH 15/20] typo fix: "class" spelling in jump game2.cpp --- LeetCode/45.jump-game2.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LeetCode/45.jump-game2.cpp b/LeetCode/45.jump-game2.cpp index 0a2bdeb..5eb0784 100644 --- a/LeetCode/45.jump-game2.cpp +++ b/LeetCode/45.jump-game2.cpp @@ -1,4 +1,4 @@ -ass Solution { +class Solution { public: int jump(vector& nums) { int n = nums.size(); From fdd00b53cebc982ca4551ee3a7d83dcc3d45871d Mon Sep 17 00:00:00 2001 From: Rachit Jain Date: Thu, 27 May 2021 23:50:03 +0530 Subject: [PATCH 16/20] LIVE_YOUTUBE - 3 DP problems --- LeetCode/1314.matrix-block-sum.cpp | 69 ++++++++++++++++++++++++++++++ LeetCode/1402.reducing-dishes.cpp | 29 +++++++++++++ LeetCode/53.maximum-subarray.cpp | 27 ++++++++++++ 3 files changed, 125 insertions(+) create mode 100644 LeetCode/1314.matrix-block-sum.cpp create mode 100644 LeetCode/1402.reducing-dishes.cpp create mode 100644 LeetCode/53.maximum-subarray.cpp diff --git a/LeetCode/1314.matrix-block-sum.cpp b/LeetCode/1314.matrix-block-sum.cpp new file mode 100644 index 0000000..2dad760 --- /dev/null +++ b/LeetCode/1314.matrix-block-sum.cpp @@ -0,0 +1,69 @@ +class Solution { +public: + vector> matrixBlockSum(vector>& mat, int k) { + int n = mat.size(), m = mat[0].size(); + vector> ans(n, vector(m, 0)); + vector> dp(n+1, vector(m+1, 0)); // 1-based indexing <-- prefix sums,˘ + + // compute the prefix sums + for(int i = 1; i <= n; i++) { + for(int j = 1; j <= m; j++) { + dp[i][j] = mat[i-1][j-1] + dp[i][j-1] + dp[i-1][j] - dp[i-1][j-1]; + } + } + + for(int i = 0; i < n; i++) { + for(int j = 0; j < m; j++) { + // compute the ans for (i,j) + int i1 = max(0, i-k), j1 = max(0,j-k); + int i2 = min(n-1, i+k), j2 = min(m-1, j+k); + i1++, i2++, j1++, j2++; //1-based indexing + + ans[i][j] = dp[i2][j2] - dp[i2][j1-1] - dp[i1-1][j2] + dp[i1-1][j1-1]; + } + },™ + return ans; + } +}; + +/* +prefix sum in 2d approach +dp[i][j] = sum of rect from (0,0) to (i,j) as diagnal points +=> it helps me in computing any rectangle sum in O(1) +(i1, j1) and (i2, j2) i1 < i2 and j1 < j2 + +dp[i2][j2] - dp[i1][j1-1] - dp[i1-1][j2] + dp[i1-1][j1-1] + + + +prefix sums can be used for each row individually +=> for given row, sum(j-k, j+k) => O(1) + j-k j j+k + + +i-k + + + +i x + + + +i+k + +(i,j) => O(k^2) +O(N^2k^2) +O(N^2 k) + + + + +k = 1 +[1,2,3], +[4,5,6], +[7,8,9] + +9*10/2 = 45 + + 5+6+8+9 = 28 +*/ diff --git a/LeetCode/1402.reducing-dishes.cpp b/LeetCode/1402.reducing-dishes.cpp new file mode 100644 index 0000000..4acb0e4 --- /dev/null +++ b/LeetCode/1402.reducing-dishes.cpp @@ -0,0 +1,29 @@ +class Solution { +public: + int maxSatisfaction(vector& arr) { + int n = arr.size(); + sort(arr.begin(), arr.end()); + int ans = 0; + for(int i = 0; i < n; i++) { + int cur = 0; + // considering the suffix from pos i + // [arr[i], arr[i+1], ... arr[n-1]] + // 1 2 + for(int j = i; j < n; j++) { + cur += (j-i+1) * arr[j]; + } + ans = max(ans, cur); + } + return ans; + } +}; + +/* +a1 <= a2 <= a3 .... // we have proved +(a1,a2,...,ak) <-- reordering of satisfaction array + you can remove elements +max(a1 + 2*a2 + 3*a3 + k*ak) + + -9 -8 -1 0 5 + + how long a prefix would you remove to get the max score +*/ diff --git a/LeetCode/53.maximum-subarray.cpp b/LeetCode/53.maximum-subarray.cpp new file mode 100644 index 0000000..019d5d2 --- /dev/null +++ b/LeetCode/53.maximum-subarray.cpp @@ -0,0 +1,27 @@ +class Solution { +public: + int maxSubArray(vector& nums) { + int n = nums.size(); + int ans = INT_MIN; + + // vector dp(n+1, 0); // O(N) extra space + // dp[i] = max subarray sum starting from index i + // mandate to pick something + int nextMax = 0; + for(int i = n-1; i >= 0; i--) { + // dp[i] = max(nums[i] + dp[i+1], 0) + // dp[i] = nums[i] + max(dp[i+1], 0); + int curMax = nums[i] + max(nextMax, 0); + ans = max(ans, curMax); + nextMax = curMax; + } + + return ans; + } +}; + +/* +_ _ _ _ _ 100 _ _ _ _ _ + i ^ + dp[i] = max(nums[i] + dp[i+1], 0) +*/ From d999e0d1396905d49c73a49323edb697b5ff3666 Mon Sep 17 00:00:00 2001 From: Rachit Jain Date: Sat, 29 May 2021 00:00:09 +0530 Subject: [PATCH 17/20] LIVE_YOUTUBE - graphs and dp problem --- LeetCode/1306.jump-game3.cpp | 26 +++++++++++++++ LeetCode/542.01-matrix.cpp | 63 ++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 LeetCode/1306.jump-game3.cpp create mode 100644 LeetCode/542.01-matrix.cpp diff --git a/LeetCode/1306.jump-game3.cpp b/LeetCode/1306.jump-game3.cpp new file mode 100644 index 0000000..4886804 --- /dev/null +++ b/LeetCode/1306.jump-game3.cpp @@ -0,0 +1,26 @@ +class Solution { + vector nums; + set s; // what all indices are there in recursion stack + + bool isPossible(int cur) { // can we reach a zero from cur index + if (s.find(cur) != s.end()) { + return false; // we detected a cycle / deadlock + } + if(0 <= cur && cur < nums.size()) { + if(nums[cur] == 0) return true; + s.insert(cur); + bool ans = false; + if (isPossible(cur + nums[cur])) ans = true; + else if (isPossible(cur - nums[cur])) ans = true; + s.erase(cur); + return ans; + } + return false; + } +public: + bool canReach(vector& arr, int start) { + //dp[i] <-- is it possible to reach a zero from i + nums = arr; + return isPossible(start); + } +}; diff --git a/LeetCode/542.01-matrix.cpp b/LeetCode/542.01-matrix.cpp new file mode 100644 index 0000000..1300106 --- /dev/null +++ b/LeetCode/542.01-matrix.cpp @@ -0,0 +1,63 @@ +using loc = pair; +int dx[] = {1, -1, 0, 0}; +int dy[] = {0, 0, 1, -1}; +class Solution { +public: + vector> updateMatrix(vector>& mat) { + int n = mat.size(), m = mat[0].size(); + + vector> dis(n, vector(m, INT_MAX)); + // dis[i][j] = nearest distance (i, j) to nearest 0 + + queue q; + for(int i = 0; i < n; i++) { + for(int j = 0; j < m; j++) { + if (mat[i][j] == 0) { + q.push({i, j}); + dis[i][j] = 0; + } + } + } + + while(!q.empty()) { + // loc cur = q.front(); + // int x = cur.first, y = cur.second; + auto [x, y] = q.front(); // current loc in mat, structured binding in C++ + q.pop(); + // (2,3) -> (1, 3) up, (3, 3) down, +1 -1 on the columns as well + for(int k = 0; k < 4; k++) { + int nx = x + dx[k], ny = y + dy[k]; + if (0 <= nx && nx < n && 0 <= ny && ny < m) { + // valid neighbour + if (dis[nx][ny] == INT_MAX) { + dis[nx][ny] = 1 + dis[x][y]; + q.push({nx, ny}); + } + } + } + } + + return dis; + } +}; + +/* +// BFS gives the shortest path in unweighted graphs + +n * m <--- 0s and 1s + + for every 1: + compute the smallest distance to 0 + +dis[i][j] = 0 where mat[i][j] = 0 + +queue<> Q = {(i,j)} where mat[i][j] = 0; + +cur = Q.front(); + +for(nei in neighbors(cur)) { + dis[nei] = 1 + dis[cur] if nei is not alreaady in queue +} + +*/ + From 12db8aa431c839def39a77d7182ccdd15085da8f Mon Sep 17 00:00:00 2001 From: Rachit Jain Date: Tue, 1 Jun 2021 18:57:51 +0530 Subject: [PATCH 18/20] youtube_live strings and dp Livestream: https://www.youtube.com/watch?v=lU6dNcpCzPU Problems solved: https://leetcode.com/problems/unique-email-addresses/ https://leetcode.com/problems/find-and-replace-pattern https://leetcode.com/problems/palindromic-substrings/ https://leetcode.com/problems/find-the-longest-substring-containing-vowels-in-even-counts/ --- ...tring-containing-vowels-in-even-counts.cpp | 59 +++++++++++++++++++ LeetCode/647.panlindrmoic-substrings.cpp | 39 ++++++++++++ LeetCode/890.find-and-replace-patterns.cpp | 45 ++++++++++++++ LeetCode/929.unique-email-address.cpp | 32 ++++++++++ 4 files changed, 175 insertions(+) create mode 100644 LeetCode/1371.find-the-longest-substring-containing-vowels-in-even-counts.cpp create mode 100644 LeetCode/647.panlindrmoic-substrings.cpp create mode 100644 LeetCode/890.find-and-replace-patterns.cpp create mode 100644 LeetCode/929.unique-email-address.cpp diff --git a/LeetCode/1371.find-the-longest-substring-containing-vowels-in-even-counts.cpp b/LeetCode/1371.find-the-longest-substring-containing-vowels-in-even-counts.cpp new file mode 100644 index 0000000..774d42c --- /dev/null +++ b/LeetCode/1371.find-the-longest-substring-containing-vowels-in-even-counts.cpp @@ -0,0 +1,59 @@ +string vowels = "aeiou"; +class Solution { +public: + int findTheLongestSubstring(string s) { + int n = s.size(); + int ans = 0; + unordered_map> pref = {}; + for (char v: vowels) pref[v] = {0}; + + for(char cur: s) { + for(char v: vowels) { + int last_parity = *pref[v].rbegin(); + if (cur == v) pref[v].push_back(1 - last_parity); + else pref[v].push_back(last_parity); + } + } + + auto get_column = [&](int j) { // 1 based + int id = 0; + for(char v: vowels) { + int x = pref[v][j]; + id = 2*id + x; + } + return id; + }; + + int rightmost[33]; + rightmost[0] = 0; + for (int i = 1; i <= n; i++) { + int id = get_column(i); + rightmost[id] = i; + } + + for (int i = 1; i <= n; i++) { + // find the rightmost j substring(i, j) is valid + // ith column + int id = get_column(i-1); + int j = rightmost[id]; + if (j < i) continue; + ans = max(ans, j-i+1); + } + return ans; + } +}; + +/* +_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + i ^ ^ + maintain prefix count of all vowels pref[a][7] + a,b,a,e,e,a,e + i j +a - 0,1,1,0,0,0,1,1 +e - 0,0,0,0,1,0,0,1 +i - ...,1,.....,1 +o - ...,0,.....,1 +u - ...,0,.....,0 +10100 <-- 20 +n^2 substrings -> O(n) => overall O(n^3) +*/ \ No newline at end of file diff --git a/LeetCode/647.panlindrmoic-substrings.cpp b/LeetCode/647.panlindrmoic-substrings.cpp new file mode 100644 index 0000000..3f95980 --- /dev/null +++ b/LeetCode/647.panlindrmoic-substrings.cpp @@ -0,0 +1,39 @@ +class Solution { +public: + int countSubstrings(string s) { + int n = s.size(); + vector> dp(n, vector(n, 0)); + for(int i = 0; i < n; i++) + dp[i][i] = 1; + + // fill this dp + for(int len = 2; len <= n; len++) { + for(int i = 0; i + len - 1 < n; i++) { + // starting from i, and length len + int j = i + len - 1; + if (i+1 == j) { + dp[i][j] = s[i] == s[j]; + } + else { + dp[i][j] = s[i] == s[j] && dp[i+1][j-1]; + } + } + } + + int ans = 0; + for(int i = 0; i < n; i++) + for(int j = 0; j < n; j++) + ans += dp[i][j]; + return ans; + } +}; +/* +for substring in all_subtrings; + if palindrome(substring) + ans++; + + +dp[i][j] = substring(i, i+1, ..., j) = is this a palindrome + +s[i] == s[j] && dp[i+1][j-1] should be true +*/ \ No newline at end of file diff --git a/LeetCode/890.find-and-replace-patterns.cpp b/LeetCode/890.find-and-replace-patterns.cpp new file mode 100644 index 0000000..934033e --- /dev/null +++ b/LeetCode/890.find-and-replace-patterns.cpp @@ -0,0 +1,45 @@ +class Solution { + bool matches(string word, string pattern) { + int n = word.size(); + vector forward(26, -1), backward(26, -1); + // map forward, backward; unordered_map + for(int i = 0; i < n; i++) { + int x = word[i] - 'a', y = pattern[i] - 'a'; + // I am trying to map x to y + if(forward[x] != -1 && forward[x] != y) return false; + if(backward[y] != -1 && backward[y] != x) return false; + forward[x] = y; + backward[y] = x; + } + + return true; + } + +public: + vector findAndReplacePattern(vector& words, string pattern) { + vector ans = {}; + // O(n * k) k is avg word size + for (auto word: words) { + if (matches(word, pattern)) ans.push_back(word); + } + + return ans; + } +}; + +/* abb xyy yxx + +// abbccc +// matches - xyyzzz yzzxxx +// does not match - xyyxxx + +abbccc yzzxxx +abbccc xyyxxx + +if a is mapped to y, then - + - a shall never be mapped to anything else + - no other char shall be mapped to y + +math background - +1:1 mapping +*/ \ No newline at end of file diff --git a/LeetCode/929.unique-email-address.cpp b/LeetCode/929.unique-email-address.cpp new file mode 100644 index 0000000..64aa042 --- /dev/null +++ b/LeetCode/929.unique-email-address.cpp @@ -0,0 +1,32 @@ +class Solution { + string get_normalized(string email) { + int i; + string local_name = ""; + bool ignore_chars = false; + for(i = 0; i < email.size(); i++) { + char c = email[i]; + if (c == '@') { + break; + } + + if (c == '.' || ignore_chars) continue; + if (c == '+') { + ignore_chars = true; + continue; + } + + local_name += c; + } + string domain = email.substr(i); + return local_name + domain; + } +public: + int numUniqueEmails(vector& emails) { + set email_set; + for(string email: emails) { + email_set.insert(get_normalized(email)); + } + + return email_set.size(); + } +}; \ No newline at end of file From 8d15a9a3ec9dfc8a08ad7aedba85a447446d68a7 Mon Sep 17 00:00:00 2001 From: Rachit Jain Date: Sun, 13 Jun 2021 19:03:01 +0530 Subject: [PATCH 19/20] youtube_live - medium problems speedrun Discord: https://bit.ly/discord-rachit Here's the link to the livestream: https://bit.ly/3iJdosx https://leetcode.com/problems/minimum-number-of-operations-to-move-all-balls-to-each-box/ https://leetcode.com/problems/deepest-leaves-sum https://leetcode.com/problems/group-the-people-given-the-group-size-they-belong-to/ https://leetcode.com/problems/queries-on-a-permutation-with-key/ --- ...le-given-the-group-size-they-belong-to.cpp | 29 +++++++++++++++ LeetCode/1302.deepest-leaves-sum.cpp | 31 ++++++++++++++++ ...1409.queries-on-a-permutation-with-key.cpp | 28 ++++++++++++++ ...erations-to-move-all-balls-to-each-box.cpp | 37 +++++++++++++++++++ 4 files changed, 125 insertions(+) create mode 100644 LeetCode/1282.group-the-people-given-the-group-size-they-belong-to.cpp create mode 100644 LeetCode/1302.deepest-leaves-sum.cpp create mode 100644 LeetCode/1409.queries-on-a-permutation-with-key.cpp create mode 100644 LeetCode/1769.minimum-number-of-operations-to-move-all-balls-to-each-box.cpp diff --git a/LeetCode/1282.group-the-people-given-the-group-size-they-belong-to.cpp b/LeetCode/1282.group-the-people-given-the-group-size-they-belong-to.cpp new file mode 100644 index 0000000..cb6d854 --- /dev/null +++ b/LeetCode/1282.group-the-people-given-the-group-size-they-belong-to.cpp @@ -0,0 +1,29 @@ +class Solution { +public: + vector> groupThePeople(vector& groupSizes) { + int n = groupSizes.size(); + unordered_map> peopleInGroupSize = {}; + for(int i = 0; i < n; i++) { + int curSize = groupSizes[i]; + peopleInGroupSize[curSize].push_back(i); + } + vector> ans = {}; + for(auto [groupSize, people]: peopleInGroupSize) { + // start making groups of |groupSize| + vector cur = {}; + for(int i = 0; i < people.size(); i++) { + cur.push_back(people[i]); + if ( cur.size() == groupSize) { + ans.push_back(cur); + cur = {}; + } + } + } + return ans; + } +}; +/* +[group_size] --> [ids of people in it] +[3] --> [0,1,2,3,4,6] +[1] --> [5] + */ \ No newline at end of file diff --git a/LeetCode/1302.deepest-leaves-sum.cpp b/LeetCode/1302.deepest-leaves-sum.cpp new file mode 100644 index 0000000..a1c3e27 --- /dev/null +++ b/LeetCode/1302.deepest-leaves-sum.cpp @@ -0,0 +1,31 @@ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode() : val(0), left(nullptr), right(nullptr) {} + * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} + * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} + * }; + */ +class Solution { + pair getDepthAndSum(TreeNode* root) { + if (root == NULL) return {0, 0}; + if (root->left == NULL and root->right == NULL) + return {1, root->val}; + + auto [left_depth, left_sum] = getDepthAndSum(root->left); + auto [right_depth, right_sum] = getDepthAndSum(root->right); + + if (left_depth == right_depth) + return {1 + left_depth, left_sum + right_sum}; + if (left_depth > right_depth) + return {1 + left_depth, left_sum}; + return {1 + right_depth, right_sum}; + } +public: + int deepestLeavesSum(TreeNode* root) { + return getDepthAndSum(root).second; + } +}; \ No newline at end of file diff --git a/LeetCode/1409.queries-on-a-permutation-with-key.cpp b/LeetCode/1409.queries-on-a-permutation-with-key.cpp new file mode 100644 index 0000000..4c5b09e --- /dev/null +++ b/LeetCode/1409.queries-on-a-permutation-with-key.cpp @@ -0,0 +1,28 @@ +class Solution { +public: + vector processQueries(vector& queries, int m) { + unordered_map pos, rev_pos; // pos[3] - 10 => 3 occurs at index 10 + for(int i = 1; i <= m; i++) { + pos[i] = i-1, rev_pos[i-1] = i; + } + + vector ans = {}; + for(int q: queries) { + ans.push_back(pos[q]); + // increment the pos of all nos from 0 to pos[q]-1 + for (int i = pos[q]-1 ; i >= 0; i--) { + int cur = rev_pos[i]; + pos[cur] = i+1; // shift to right side + rev_pos[i+1] = cur; + } + pos[q] = 0; + rev_pos[0] = q; + } + return ans; + } +}; +// 1,2,3,4,5 +// 3,1,2,4,5 + +// _ _ _ _ _ _ _ _ _ _ _ + // ^ \ No newline at end of file diff --git a/LeetCode/1769.minimum-number-of-operations-to-move-all-balls-to-each-box.cpp b/LeetCode/1769.minimum-number-of-operations-to-move-all-balls-to-each-box.cpp new file mode 100644 index 0000000..a6f539c --- /dev/null +++ b/LeetCode/1769.minimum-number-of-operations-to-move-all-balls-to-each-box.cpp @@ -0,0 +1,37 @@ +class Solution { +public: + vector minOperations(string boxes) { + int n = boxes.size(); + int left_cnt = 0, tot_cnt = 0; // cnt of 1s + int left_sum = 0, tot_sum = 0; // sum of indices where its a 1 + + + for(int i = 0; i < n; i++) { + if (boxes[i] == '1') tot_cnt++, tot_sum += i; + } + + vector ans = {}; + for(int i = 0; i < n; i++) { + int right_cnt = tot_cnt - left_cnt; + int right_sum = tot_sum - left_sum; + + int left = left_cnt * i - left_sum; + int right = right_sum - right_cnt * i; + ans.push_back(left + right); + + if (boxes[i] == '1') left_cnt++, left_sum += i; + } + return ans; + } +}; + + +/* +i=13 +j<13 +i-j1 + i-j2 => 2*i - (j1+j2) + +j>13 +j1-i + j2-i => (j1+j2) - 2 *(i) +*/ + From da7e12d0b02e2c6dd3764c4ecc2b0853d16e8891 Mon Sep 17 00:00:00 2001 From: Rachit Jain <32428330+rachitiitr@users.noreply.github.com> Date: Sat, 16 Mar 2024 07:49:33 +0000 Subject: [PATCH 20/20] Codeforces Contest Runner and Debug Logger during Local --- .gitignore | 5 +- Library/Miscellanious/template2024.cpp | 41 +++++++++ Library/Utils/bits/stdc++.h | 117 +++++++++++++++++++++++++ Library/Utils/codeforces.sh | 30 +++++++ Library/Utils/logger.h | 108 +++++++++++++++++++++++ 5 files changed, 300 insertions(+), 1 deletion(-) create mode 100644 Library/Miscellanious/template2024.cpp create mode 100644 Library/Utils/bits/stdc++.h create mode 100644 Library/Utils/codeforces.sh create mode 100644 Library/Utils/logger.h diff --git a/.gitignore b/.gitignore index d99efa9..aa1d2cc 100644 --- a/.gitignore +++ b/.gitignore @@ -29,4 +29,7 @@ # Executables *.exe *.out -*.app \ No newline at end of file +*.app + +# Temp Codeforces Contest Env +CodeforcesContestRunner \ No newline at end of file diff --git a/Library/Miscellanious/template2024.cpp b/Library/Miscellanious/template2024.cpp new file mode 100644 index 0000000..8c129f4 --- /dev/null +++ b/Library/Miscellanious/template2024.cpp @@ -0,0 +1,41 @@ +#include +#ifndef ONLINE_JUDGE + #include "logger.h" +#else + #define deb(...) + #define deb(...) +#endif +using namespace std; +#define ll long long +#define all(x) x.begin(), x.end() +int mpow(int base, int exp); +//======================= +const int MOD = 1'000'000'007; +const int N = 2003, M = N; +vector g[N]; +int a[N]; + +void solve() { + +} + +int main() { + ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0); + int t = 1; + cin >> t; + while(t--) { + solve(); + } + return 0; +} + +int mpow(int base, int exp) { + base %= MOD; + int result = 1; + while (exp > 0) { + if (exp & 1) result = ((ll)result * base) % MOD; + base = ((ll)base * base) % MOD; + exp >>= 1; + } + return result; +} \ No newline at end of file diff --git a/Library/Utils/bits/stdc++.h b/Library/Utils/bits/stdc++.h new file mode 100644 index 0000000..4886b92 --- /dev/null +++ b/Library/Utils/bits/stdc++.h @@ -0,0 +1,117 @@ +// C++ includes used for precompiling -*- C++ -*- + +// Copyright (C) 2003-2015 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +/** @file stdc++.h + * This is an implementation file for a precompiled header. + */ + +// 17.4.1.2 Headers + +// C +#ifndef _GLIBCXX_NO_ASSERT +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if __cplusplus >= 201103L +#include +#include +#include +// #include +#include +#include +#include +#include +#include +#endif + +// C++ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if __cplusplus >= 201103L +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif \ No newline at end of file diff --git a/Library/Utils/codeforces.sh b/Library/Utils/codeforces.sh new file mode 100644 index 0000000..444da0b --- /dev/null +++ b/Library/Utils/codeforces.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# Get the root directory of the Git repository +GIT_ROOT=$(git rev-parse --show-toplevel) + +function enter() { + mkdir -p $GIT_ROOT/CodeforcesContestRunner; + cd $GIT_ROOT/CodeforcesContestRunner; + cp $GIT_ROOT/Library/Miscellanious/template2024.cpp a.cpp + cp $GIT_ROOT/Library/Miscellanious/template2024.cpp b.cpp + cp $GIT_ROOT/Library/Miscellanious/template2024.cpp c.cpp + cp $GIT_ROOT/Library/Miscellanious/template2024.cpp d.cpp + cp $GIT_ROOT/Library/Miscellanious/template2024.cpp e.cpp + echo '' > in.txt +} + +function build() { + problem=$1 + g++ -std=c++20 $problem.cpp -o run_$problem -isystem $GIT_ROOT/Library/Utils +} + +function run() { + problem=$1 + ./run_$problem +} + +function runtxt() { + problem=$1 + ./run_$problem < in.txt +} \ No newline at end of file diff --git a/Library/Utils/logger.h b/Library/Utils/logger.h new file mode 100644 index 0000000..593d3a7 --- /dev/null +++ b/Library/Utils/logger.h @@ -0,0 +1,108 @@ +#include +// #define cerr cout +namespace __DEBUG_UTIL__ +{ + using namespace std; + template + concept is_iterable = requires(T &&x) { begin(x); } && + !is_same_v, string>; + void print(const char *x) { cerr << x; } + void print(char x) { cerr << "\'" << x << "\'"; } + void print(bool x) { cerr << (x ? "T" : "F"); } + void print(string x) { cerr << "\"" << x << "\""; } + void print(vector &v) + { /* Overloaded this because stl optimizes vector by using + _Bit_reference instead of bool to conserve space. */ + int f = 0; + cerr << '{'; + for (auto &&i : v) + cerr << (f++ ? "," : "") << (i ? "T" : "F"); + cerr << "}"; + } + template + void print(T &&x) + { + if constexpr (is_iterable) + if (size(x) && is_iterable) + { /* Iterable inside Iterable */ + int f = 0; + cerr << "\n~~~~~\n"; + for (auto &&i : x) + { + cerr << setw(2) << left << f++, print(i), cerr << "\n"; + } + cerr << "~~~~~\n"; + } + else + { /* Normal Iterable */ + int f = 0; + cerr << "{"; + for (auto &&i : x) + cerr << (f++ ? "," : ""), print(i); + cerr << "}"; + } + else if constexpr (requires { x.pop(); }) /* Stacks, Priority Queues, Queues */ + { + auto temp = x; + int f = 0; + cerr << "{"; + if constexpr (requires { x.top(); }) + while (!temp.empty()) + cerr << (f++ ? "," : ""), print(temp.top()), temp.pop(); + else + while (!temp.empty()) + cerr << (f++ ? "," : ""), print(temp.front()), temp.pop(); + cerr << "}"; + } + else if constexpr (requires { x.first; x.second; }) /* Pair */ + { + cerr << '(', print(x.first), cerr << ',', print(x.second), cerr << ')'; + } + else if constexpr (requires { get<0>(x); }) /* Tuple */ + { + int f = 0; + cerr << '(', apply([&f](auto... args) + { ((cerr << (f++ ? "," : ""), print(args)), ...); }, + x); + cerr << ')'; + } + else + cerr << x; + } + template + void printer(const char *names, T &&head, V &&...tail) + { + int i = 0; + for (size_t bracket = 0; names[i] != '\0' and (names[i] != ',' or bracket != 0); i++) + if (names[i] == '(' or names[i] == '<' or names[i] == '{') + bracket++; + else if (names[i] == ')' or names[i] == '>' or names[i] == '}') + bracket--; + cerr.write(names, i) << " = "; + print(head); + if constexpr (sizeof...(tail)) + cerr << " ||", printer(names + i + 1, tail...); + else + cerr << "]\n"; + } + template + void printerArr(const char *names, T arr[], size_t N, V... tail) + { + size_t i = 0; + for (; names[i] and names[i] != ','; i++) + cerr << names[i]; + for (i++; names[i] and names[i] != ','; i++) + ; + cerr << " = {"; + for (size_t ind = 0; ind < N; ind++) + cerr << (ind ? "," : ""), print(arr[ind]); + cerr << "}"; + if constexpr (sizeof...(tail)) + cerr << " ||", printerArr(names + i + 1, tail...); + else + cerr << "]\n"; + } + +} +#define deb(...) std::cerr << __LINE__ << ": [", __DEBUG_UTIL__::printer(#__VA_ARGS__, __VA_ARGS__) +#define debArr(...) std::cerr << __LINE__ << ": [", __DEBUG_UTIL__::printerArr(#__VA_ARGS__, __VA_ARGS__) \ No newline at end of file