├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── Striver CP Sheet └── Readme.md └── Striver SDE Sheet ├── Day - 1 (Arrays) ├── Dutch Flag Algorithm.cpp ├── Find duplicate in array.cpp ├── Kadane Algorithm.cpp ├── Merge 2 Sorted Arr (No Extra Space). cpp ├── Merge Overlapping SubIntervals.cpp └── Repeat And Missing Number.cpp ├── Day - 10 (Recursion&Backtracking) ├── M Colouring Problem.cpp ├── N Queens Problem.cpp ├── Permutation in String.cpp ├── Rat in a Maze.cpp └── Sudoku.cpp ├── Day - 11 (Binary Search) ├── Kth Element Of Two Sorted Arrays.cpp ├── Matrix Median.cpp ├── Median of 2 sorted arrays(Hard).cpp ├── Search element in sorted rotated array.cpp ├── Single Element in Sorted Array.cpp └── Sqrt(x).cpp ├── Day - 12 (Bits) ├── Count Total Set Bits.cpp ├── Counting Bits.cpp ├── Most Significant Bit.cpp ├── Power of 2.cpp └── Subsets.cpp ├── Day - 13 (Stacks and Queues) ├── BFS.cpp ├── Balanced Parenthesis.cpp ├── Implement Queue using Stack.cpp ├── Implement Stack using Queue.cpp └── Next Greater Element.cpp ├── Day - 14 ├── Implement Min Stack.cpp ├── LRU Cache (Hard)(VVIP).cpp ├── Largest Rectangle In A Histogram.cpp ├── Next Smaller Element.cpp ├── Rotten Oranges.cpp └── Sliding Window Maximum.cpp ├── Day - 15 (Strings) ├── Implement ATOI and STRSTR.cpp ├── Longest Common Prefix.cpp ├── Longest Palindrome substring.cpp ├── Reverse words in String.cpp └── Roman No. to Integer and vice versa.cpp ├── Day - 16 (Strings) ├── Check for anagrams.cpp ├── Compare Version Numbers.cpp └── Count and Say.cpp ├── Day - 17 (Binary Tree) ├── Bottom View Of Binary Tree.cpp ├── Inorder Iterative.cpp ├── Inorder Recursive.cpp ├── Inorder Traversal(both).cpp ├── Left View Of Binary Tree.cpp ├── Postorder (both).cpp ├── Postorder Iterative.cpp ├── Postorder Recursive.cpp ├── Preorder (both).cpp ├── Preorder Iterative.cpp ├── Preorder Recursive.cpp ├── Right View of Binary Tree.cpp └── Top View Of Binary Tree.cpp ├── Day - 18 (Binary Tree) ├── Check if trees identical.cpp ├── Diameter of tree.cpp ├── Height balanced Check.cpp ├── Height of Binary Tree.cpp ├── LCA in Binary Tree.cpp ├── Level Order Traversal.cpp └── Level order in Spiral.cpp ├── Day - 19 (Binary Tree) ├── Construct BTree from Inorder and Postorder.cpp ├── Construct BTree from Inorder and Preorder(Hard).cpp ├── Flatten BTree to LinkedList.cpp ├── Maximum Path Sum(Hard).cpp └── Symmetric Tree(Mirror of itself).cpp ├── Day - 2 (Arrays) ├── Best Time to Buy and Sell Stock - 1.cpp ├── Inversion Count.cpp ├── Next Permutation.cpp ├── Pascal Triangle. cpp ├── Rotate Matrix.cpp └── Set Matrix Zeros. cpp ├── Day - 20 (BST) ├── Check if BT is BST.cpp ├── Construct BST from given keys.cpp ├── Inorder predecessor and succ in BST.cpp ├── LCA of BST.cpp ├── Populate next right pointers.cpp └── Search in BST.cpp ├── Day - 21 (BST) ├── BST Iterator.cpp ├── Find pair with sum in BST.cpp ├── Floor and ceil of BST.cpp ├── K-th largest element in BST.cpp ├── K-th smallest in BST.cpp ├── Max sum BST in BT(Hard).cpp └── Serialize and Deserialize(Hard).cpp ├── Day - 23 (Graphs) ├── BFS.cpp ├── Bipartite Check(BFS).cpp ├── Bipartite Check(DFS).cpp ├── Clone a Graph (DFS)(Hard).cpp ├── Cycle Detection Directed Graph (BFS)(Kahn).cpp ├── Cycle Detection Directed Graph(DFS).cpp ├── Cycle Detection Undirected Graph(BFS)(Hard).cpp ├── Cycle Detection Undirected Graph(DFS).cpp ├── DFS.cpp ├── Topological Sort (BFS)(Kahn).cpp └── Topological Sort(DFS).cpp ├── Day - 24 (Graphs) ├── Articulation Point (VHard).cpp ├── Bellman Ford's Algo.cpp ├── Bridges in Graph (VHard).cpp ├── Dijkstra's Algo.cpp ├── Disjoint Set(Union by rank and Path Compression).cpp ├── Floyd Warshall Algo.cpp ├── Kruskal's Algo(Hard).cpp ├── Prim's Algo.cpp ├── Shortest Path DAG(Hard).cpp ├── Shortest Path Undirected Graph.cpp └── Strongly Connected Components (Kosaraju).cpp ├── Day - 25 (DP) ├── 0-1 Knapsack (all methods).cpp ├── Edit Distance.cpp ├── Longest Common Subsequence.cpp ├── Longest Inc Subsequence.cpp ├── Matrix Chain Multiplication(Hard).cpp ├── Max Sum Inc Subsequence (MSIS).cpp └── Maximum Product Subarray.cpp ├── Day - 26 (DP) ├── Climbing Stairs.cpp ├── Coin Change (2 methods).cpp ├── Egg Dropping(Hard).cpp ├── Max Profit Job scheduling(Hard).cpp ├── Max Sum Path in Matrix(2 methods).cpp ├── Rod Cutting.cpp ├── Subset Sum.cpp └── Word Break.cpp ├── Day - 3 (Arrays&Math) ├── Majority Element - 2.cpp ├── Majority Element.cpp ├── Search 2-D Matrix.cpp ├── Unique Paths.cpp └── pow(X,n).cpp ├── Day - 4 (Hashing) ├── 2 Sum.cpp ├── 4 Sum.cpp ├── Largest Subarray with 0 sum.cpp └── Longest Consecutive Sequence.cpp ├── Day - 5 (Linked List) ├── Add 2 Linked List Numbers.cpp ├── Delete Node In A Linked List.cpp ├── Merge Two Sorted Lists.cpp ├── Middle Of Linked List.cpp ├── Remove Nth Node from End of List.cpp └── Reverse Linked List.cpp ├── Day - 6 (Linked List) ├── Find The Starting Point Of Loop.cpp ├── Intersection of 2 LinkedLists.cpp ├── Linked List Cycle.cpp ├── Palindrome Linked List.cpp └── Reverse Nodes In K Group.cpp ├── Day - 7 (2 pointer) ├── 3 Sum.cpp ├── Clone A Linked List With Random And Next Pointer.cpp ├── Max Consecutive Ones.cpp ├── Remove Duplicates from Sorted Array.cpp └── Trapping Rain Water.cpp ├── Day - 8 (Greedy) ├── Coin Change.cpp ├── Fractional Knapsack.cpp ├── Job Sequencing Problem.cpp ├── Minimum Platforms.cpp └── N meetings in one room.cpp └── Day - 9 (Recursion) ├── Combination Sum-1.cpp ├── Combination Sum-2.cpp ├── Palindrome Partitioning.cpp ├── Permutation Sequence.cpp ├── Subset Sums.cpp └── Subset-2.cpp /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # RULES OF CONTRIBUTING 2 | 3 | - Within 100 Days of Leetcode folder, add folders for each day. Format : Day - X 4 | - For each sum you do, write the fullname of the question fully. e.g. Fractional Knapsack.cpp. Name **MUST** match the exact question name in Leetcode. 5 | - Add all the programs you **All** did that day within that day's folder i.e. everyone shares the same day folder. 6 | - Make sure there is **NO** repetition of questions whatsoever. Check the repo before solving a question 7 | - If you are providing a better way to solve an already present question, make a comment below existing code e.g. # Method-2 and then paste your code below comment 8 | - Before submission,make sure the code works on whatever platform you ran it in e.g.Leetcode, or GFG 9 | - If you can add small comments in the code to explain your thought process, that would help you when revising. 10 | - **No spam codes/incomplete codes will be allowed** 11 | 12 | > 100 Days of Leetcode -> Create folder "Day - x" (same format) -> All contributors add the Leetcode questions they did on that day. No overlaps. If 2 people solved the same qn, one of you can decide to commit and the other one should not (unless it is a different method. See point 5) 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 HariHaran 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Striver SDE Sheet Solutions (C++) 3 | 4 |

5 | 6 | ![Striver-SDE-Sheet-Resources](https://socialify.git.ci/Leet-Us-Code/Striver-SDE-Sheet-Resources/image?description=1&descriptionEditable=C%2B%2B%20solutions%20to%20all%20the%20problems%20on%20the%20famous%20SDE%20Sheet%20(updated%20regularly!)&font=Source%20Code%20Pro&forks=1&issues=1&language=1&owner=1&pattern=Circuit%20Board&pulls=1&stargazers=1&theme=Dark) 7 |

8 | 9 |

This is everything you need to ace your coding interviews! ✨

10 | 11 | ## 🎯 Purpose 12 | After the huge success of my [**Javascript A-Z Notes repository**](https://github.com/HariAcidReign/JavaScript-A-Z-Notes), I had been toying with the idea to make a repo for all the questions in the SDE Sheet. This might be of massive help especially if you are preparing for placements and want a quick revision of the problems before your OA or interviews 🔥 (Almost) All the questions have 2 ways of solving (mine and my friend's) + **every answer has detailed comments for every step** 13 | 14 | I myself used the **SDE Sheet** extensively and was able to bag an offer for 6 months (Jan-Jun) internship at **Amazon** and became one of the 8 people to get selected for this on-campus opportunity from over a 1000 candidates!🥳 So, here is my way of saying *thank you!* to takeUforward and the TUF fam 🤎 15 | 16 | ## 🥂 Who created this? 17 | This is a painstaking effort of both **mine** and my very good friend + coding buddy [**Siddharth**](https://github.com/DiligentCoder-20022001). Go checkout our other awesome repos! 18 | 19 | ## 💗 Contributions 20 | I'll always work on my DSA skills, so expect this repo to get updated constantly. 21 | - Time and space complexities haven't been added for some questions, so if you want to start your open-source journey from here, you are most welcome to! 22 | - Also, if you have a better (and tested) implementation for any problem, feel free to add. I review PRs frequently 🤓 23 | 24 | ## 📝 Resource Used 25 | - [TakeUForward channel on Youtube ](https://www.youtube.com/channel/UCJskGeByzRRSvmOyZOz61ig) 26 | - [SDE Sheet](https://docs.google.com/document/d/1SM92efk8oDl8nyVw8NHPnbGexTS9W-1gmTEYfEurLWQ/edit?usp=sharing) 27 | -------------------------------------------------------------------------------- /Striver CP Sheet/Readme.md: -------------------------------------------------------------------------------- 1 | Here is where I will be solving the CP Sheet created by Striver to improve myself in Competitive Programming 2 | 3 | 4 | Link: https://docs.google.com/document/d/1vShwt8yXYUOgkF53-iYAuJXWR7Yi5VSJrW2xB49o0PM/edit 5 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 1 (Arrays)/Dutch Flag Algorithm.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | // https://leetcode.com/problems/sort-colors/ 3 | 4 | class Solution 5 | { 6 | public: 7 | void sortColors(vector &A) 8 | { 9 | int low = 0, mid = 0; 10 | int hi = A.size() - 1; 11 | 12 | while (mid <= hi) 13 | { 14 | if (A[mid] == 0) 15 | swap(A[mid++], A[low++]); 16 | else if (A[mid] == 1) 17 | mid++; 18 | else 19 | { 20 | // if it is 2 21 | swap(A[mid], A[hi--]); // no increment of mid. Only hi decrement as we have included mid condt in 0 and 1 case, and sometimes we get a 0 after swapping 22 | // with hi which might not get swapped with low if we incremented mid here also. 23 | } 24 | } 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 1 (Arrays)/Find duplicate in array.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | int findDuplicate(vector& nums) { 4 | int fast = nums[0], slow = nums[0]; 5 | 6 | // use do while to run first time even when fast = slow. while will simply break @ start 7 | // and do while will run any code min 1 time irrespective of condition 8 | do { 9 | fast = nums[nums[fast]]; 10 | slow = nums[slow]; 11 | } while (slow != fast); 12 | 13 | // fast will stay at meeting point and slow comes back to start 14 | slow = nums[0]; 15 | 16 | while(fast != slow){ 17 | slow = nums[slow]; 18 | fast = nums[fast]; 19 | } 20 | return slow; // return fast; 21 | } 22 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 1 (Arrays)/Kadane Algorithm.cpp: -------------------------------------------------------------------------------- 1 | // Find max contiguous subarray 2 | 3 | int maxSubArray(vector &nums) 4 | { 5 | int max_so_far = INT_MIN, max_ending_here = 0; 6 | 7 | for (int i = 0; i < nums.size(); i++) 8 | { 9 | max_ending_here += nums[i]; 10 | if (max_so_far < max_ending_here) 11 | max_so_far = max_ending_here; 12 | if (max_ending_here < 0) 13 | max_ending_here = 0; // to get only +ve ans 14 | } 15 | return max_so_far; 16 | } 17 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 1 (Arrays)/Merge 2 Sorted Arr (No Extra Space). cpp: -------------------------------------------------------------------------------- 1 | int nextGap(int x) 2 | { 3 | if(x <= 1) 4 | return 0; 5 | else 6 | return (x/2) + (x%2); 7 | } 8 | void merge(int arr1[], int arr2[], int n, int m) { 9 | // code here 10 | int i, j; 11 | int sum = m+ n; 12 | int gap = nextGap(sum); 13 | while(gap > 0) 14 | { 15 | //first array -> arr1 16 | for(i = 0; i + gap < n; i++) 17 | { 18 | if(arr1[i] > arr1[i+gap]) 19 | swap(arr1[i], arr1[i+gap]); 20 | } 21 | //for both the first and second array 22 | if(gap > n) 23 | j = gap - n; 24 | else 25 | j = 0; 26 | for(; j < m && i < n; j++, i++) 27 | { 28 | if(arr1[i] > arr2[j]) 29 | swap(arr1[i], arr2[j]); 30 | } 31 | //for the second array only 32 | if(j < m) 33 | { 34 | for(j = 0; j + gap < m; j++) 35 | { 36 | if(arr2[j] > arr2[j+gap]) 37 | swap(arr2[j], arr2[j+gap]); 38 | } 39 | } 40 | gap = nextGap(gap); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 1 (Arrays)/Merge Overlapping SubIntervals.cpp: -------------------------------------------------------------------------------- 1 | class Solution 2 | { 3 | public: 4 | vector> merge(vector> &intervals) 5 | { 6 | //OM GAN GANAPATHAYE NAMO NAMAH 7 | //JAI SHRI RAM 8 | //JAI BAJRANGBALI 9 | //AMME NARAYANA, DEVI NARAYANA, LAKSHMI NARAYANA, BHADRE NARAYANA 10 | int p1 = 0, p2 = 0; 11 | int n = intervals.size(); 12 | vector> inter; 13 | for (int i = 0; i < n; i++) 14 | { 15 | inter.push_back(make_pair(intervals[i][0], intervals[i][1])); 16 | } 17 | sort(inter.begin(), inter.end()); 18 | int k = 0; 19 | while (p1 < n && p2 < n) 20 | { 21 | inter[k].first = inter[p2].first; 22 | inter[k].second = inter[p2].second; 23 | while (p1 < n && inter[k].second >= inter[p1].first) 24 | { 25 | inter[k].first = min(inter[k].first, inter[p1].first); 26 | inter[k].second = max(inter[k].second, inter[p1].second); 27 | p1++; 28 | } 29 | k++; 30 | p2 = p1; 31 | } 32 | vector> res; 33 | for (int i = 0; i < k; i++) 34 | { 35 | vector temp; 36 | temp.push_back(inter[i].first); 37 | temp.push_back(inter[i].second); 38 | res.push_back(temp); 39 | } 40 | return res; 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 1 (Arrays)/Repeat And Missing Number.cpp: -------------------------------------------------------------------------------- 1 | int *findTwoElement(int *arr, int n) 2 | { 3 | // code here 4 | int xor1 = 0; 5 | for (int i = 0; i < n; i++) 6 | xor1 = xor1 ^ arr[i]; 7 | for (int i = 1; i <= n; i++) 8 | xor1 = xor1 ^ i; 9 | //{1,3,3} and {1,2,3} 10 | //2^3 => 5 11 | //repeating -> first arrayb 12 | //missing array -> second array 13 | //x & ~(x-1) 14 | int setBit = xor1 & (~(xor1 - 1)); 15 | int x = 0, y = 0; 16 | //first array 17 | for (int i = 0; i < n; i++) 18 | { 19 | if (arr[i] & setBit) 20 | { 21 | x = x ^ arr[i]; 22 | } 23 | else 24 | { 25 | y = y ^ arr[i]; 26 | } 27 | } 28 | //second array 29 | for (int i = 1; i <= n; i++) 30 | { 31 | if (i & setBit) 32 | { 33 | x = x ^ i; 34 | } 35 | else 36 | { 37 | y = y ^ i; 38 | } 39 | } 40 | int *res; 41 | //we ll search for x or y in the first array 42 | int flagx = 0; 43 | int flagy = 0; 44 | for (int i = 0; i < n; i++) 45 | { 46 | if (arr[i] == x) 47 | { 48 | flagx = 1; 49 | break; 50 | } 51 | else if (arr[i] == y) 52 | { 53 | flagy = 1; 54 | break; 55 | } 56 | } 57 | if (flagx == 1) 58 | { 59 | res[0] = x; 60 | res[1] = y; 61 | return res; 62 | } 63 | else 64 | { 65 | res[0] = y; 66 | res[1] = x; 67 | return res; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 10 (Recursion&Backtracking)/Permutation in String.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | bool checkInclusion(string s1, string s2) { 4 | // make 2 hashmaps for both strings 5 | vector hash1(26,0); 6 | vector hash2(26,0); 7 | int N1 = s1.size(); 8 | int N2 = s2.size(); 9 | // we have to see if s2 contains permutation of s1 10 | if(N2 < N1) return false; 11 | 12 | 13 | // first we fill up hash counts in both 14 | int left = 0, right = 0; 15 | while(right < N1){ 16 | hash1[s1[right] - 'a']++; 17 | hash2[s2[right] - 'a']++; 18 | right++; 19 | } 20 | right--; // point to end of first window 21 | 22 | while(right < N2){ 23 | if(hash1 == hash2) return true; 24 | right++; 25 | if(right != N2){ 26 | hash2[s2[right] - 'a']++; 27 | } 28 | hash2[s2[left] - 'a']--; 29 | left++; 30 | } 31 | return false; 32 | } 33 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 10 (Recursion&Backtracking)/Rat in a Maze.cpp: -------------------------------------------------------------------------------- 1 | // Hari and Sid 2 | 3 | class Solution{ 4 | public: 5 | vector findPath(vector> &m, int n) { 6 | vector res; 7 | string path; 8 | vector> seen( n , vector (n, 0)); 9 | helper(0,0,m,n, res, path, seen); 10 | return res; 11 | } 12 | 13 | bool isSafe(int row, int col, vector> &m, vector> &seen){ 14 | if(row < 0 || row >= m.size() || col < 0 || col >= m.size() || seen[row][col] == 1 || 15 | m[row][col] == 0) return false; 16 | 17 | return true; 18 | } 19 | 20 | void helper(int row, int col, vector> &m, int n, vector &res, 21 | string &path, vector> &seen){ 22 | if(row >= n || col >= n) return; // bounding case 23 | // destination reached? (base case) 24 | if(row == n-1 && col == n-1){ 25 | res.push_back(path); 26 | return; 27 | } 28 | // destination not reached 29 | if(isSafe(row, col, m, seen)){ 30 | seen[row][col] = 1; 31 | if(isSafe(row+1, col, m, seen)){ // D 32 | path.push_back('D'); 33 | helper(row+1, col, m, n, res, path, seen); 34 | path.pop_back(); 35 | } 36 | if(isSafe(row, col-1, m, seen)){ // L 37 | path.push_back('L'); 38 | helper(row, col-1, m, n, res, path, seen); 39 | path.pop_back(); 40 | } 41 | if(isSafe(row, col+1, m, seen)){ // R 42 | path.push_back('R'); 43 | helper(row, col+1, m, n, res, path, seen); 44 | path.pop_back(); 45 | } 46 | if(isSafe(row-1, col, m, seen)){ // U 47 | path.push_back('U'); 48 | helper(row-1, col, m, n, res, path, seen); 49 | path.pop_back(); 50 | } 51 | seen[row][col] = 0; 52 | } 53 | 54 | 55 | } 56 | }; 57 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 10 (Recursion&Backtracking)/Sudoku.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution { 4 | public: 5 | bool isValidSudoku(vector>& board) { 6 | // this is an ad-hoc method 7 | map row[9],col[9],blk[9]; 8 | char c; 9 | for(int i = 0;i<9;i++){ 10 | for(int j = 0;j<9;j++){ 11 | c = board[i][j]; 12 | if((c!='.')&&(0> &matrix, int r, int c){ 6 | //find the minimum element -> check the first column 7 | int minEle = INT_MAX; 8 | for(int i = 0; i < r; i++) 9 | { 10 | minEle = min(minEle, matrix[i][0]); 11 | } 12 | //find the maximum element 13 | int maxEle = INT_MAX; 14 | for(int i = 0; i < r; i++) 15 | { 16 | maxEle = max(maxEle, matrix[i][c-1]); 17 | } 18 | int res = -1; 19 | int dez = (r*c+1)/2; 20 | while(minEle < maxEle) 21 | { 22 | int mid = minEle + (maxEle - minEle)/2; 23 | //search the number of elements less than mid in the matrix 24 | int cnt = 0; 25 | for(int i = 0; i < r; i++) 26 | { 27 | cnt += upper_bound(matrix[i].begin(), matrix[i].end(), mid) - matrix[i].begin(); 28 | } 29 | if(cnt < dez) 30 | { 31 | minEle = mid+1; 32 | } 33 | else 34 | { 35 | maxEle = mid; 36 | } 37 | } 38 | return minEle; 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 11 (Binary Search)/Median of 2 sorted arrays(Hard).cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution { 4 | public: 5 | // helpers 6 | int getMax(vector nums, int part){ 7 | if(part == 0){ 8 | // if partition is in front of nums then leftX should be INT_MIN and not some random garbage value 9 | return INT_MIN; 10 | } 11 | else return nums[part-1]; 12 | } 13 | 14 | int getMin(vector nums, int part){ 15 | // if partition goes out of bounds of nums 16 | if(part == nums.size()){ 17 | return INT_MAX; 18 | } 19 | else return nums[part]; 20 | } 21 | 22 | 23 | double findMedianSortedArrays(vector& nums1, vector& nums2) { 24 | // HARD COMMON INTERVIEW DnC QN 25 | // nums1 has to be the smaller of the two 26 | if(nums1.size() > nums2.size()){ 27 | nums1.swap(nums2); 28 | } 29 | 30 | int low = 0, hi = nums1.size(); 31 | int combinedLength = nums1.size() + nums2.size(); 32 | // combinedL can either be even or odd. Flow goes based on which one it is 33 | 34 | while(low <= hi){ 35 | int partX = low + (hi-low) / 2; // partition in nums1 36 | int partY = (combinedLength + 1) / 2 - (partX); 37 | 38 | // get no. directly to left of partitions (both) 39 | int leftX = getMax(nums1, partX); 40 | int leftY = getMax(nums2, partY); 41 | 42 | // get no. directly to right of partitions (both) 43 | int rightX = getMin(nums1, partX); 44 | int rightY = getMin(nums2, partY); 45 | 46 | /* 2 conditions for both arr partitions to be valid 47 | 1. no. on left of partX (nums1) <= no. on right of partY (nums2) 48 | 2. no. on left of partY (nums2) <= no. on right of partX (nums1) 49 | */ 50 | 51 | // partitions valid check 52 | if(leftX <= rightY && leftY <= rightX){ 53 | double res; 54 | if(combinedLength % 2 == 0){ 55 | // even -> max of left partitions + min of right / 2 56 | res = (max(leftX, leftY) + min(rightX, rightY)) / 2.0; 57 | //used 2.0 for double dtype division 58 | } 59 | else { 60 | res = max(leftX, leftY); // odd->max of left sides of both partitions will give median of combined array 61 | } 62 | return res; 63 | } 64 | 65 | // if current partitions invalid 66 | if(leftX > rightY) hi = partX - 1; 67 | else if(leftY > rightX) low = partX + 1; 68 | } 69 | 70 | return -1; 71 | 72 | 73 | } 74 | 75 | }; 76 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 11 (Binary Search)/Search element in sorted rotated array.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | int search(vector& nums, int target) { 4 | // rotated array will definitely have minimum ONE strictly inc. section 5 | int N = nums.size(); 6 | int left = 0, right = N-1; 7 | 8 | while(left <= right){ 9 | int mid = left + (right-left)/2; 10 | if(nums[mid] == target) return mid; 11 | // now we check if left part of mid strictly inc. 12 | else if(nums[mid] >= nums[left]){ 13 | // check if target is in this strictly inc left part 14 | if(target >= nums[left] && target <= nums[mid]){ 15 | right = mid-1; 16 | } else { 17 | //target not in strictly inc left part. So search right 18 | left = mid+1; 19 | } 20 | } 21 | // if left part not strictly inc. 100% right part is strictly inc 22 | else { 23 | if(target >= nums[mid] && target <= nums[right]){ 24 | left = mid+1; 25 | } 26 | else right = mid-1; 27 | } 28 | } 29 | // if not found 30 | return -1; 31 | } 32 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 11 (Binary Search)/Single Element in Sorted Array.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | int singleNonDuplicate(vector& nums) { 4 | // Sorting, and hashing are 2 easy methods. This one is ad-hoc 5 | unordered_set s; 6 | int sum1 = 0, sum2 = 0; 7 | for(int it: nums) s.insert(it); 8 | for(int i: s) sum1+=i; 9 | sum1 *= 2; 10 | for(int j: nums) sum2 += j; 11 | int res = sum1 - sum2; 12 | return res; 13 | } 14 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 11 (Binary Search)/Sqrt(x).cpp: -------------------------------------------------------------------------------- 1 | // Sid 2 | 3 | class Solution { 4 | public: 5 | int mySqrt(int x) { 6 | if(x == 0) 7 | return 0; 8 | else if(x == 1) 9 | return 1; 10 | int l = 0 , r = x; 11 | int res = -1; 12 | while(l <= r) 13 | { 14 | int mid = (int)((l+r)/2); 15 | if(mid == x/mid) 16 | { 17 | return mid; 18 | } 19 | else if(mid < x/mid) 20 | { 21 | res = mid; 22 | l = mid + 1; 23 | } 24 | else 25 | { 26 | r = mid - 1; 27 | } 28 | } 29 | return res; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 12 (Bits)/Count Total Set Bits.cpp: -------------------------------------------------------------------------------- 1 | class Solution{ 2 | public: 3 | // n: input to count the number of set bits 4 | //Function to return sum of count of set bits in the integers from 1 to n. 5 | int countSetBits(int n) 6 | { 7 | if(n == 0) 8 | return 0; 9 | int b = (int)(log2(n)); 10 | int x = pow(2,b); 11 | //for the numbers above x 12 | int part1 = b*pow(2,b-1); 13 | //for the numbers below x (including the MSB alone) recur for the remaining part 14 | int part2 = (n - x + 1); 15 | return part1+part2+countSetBits(n-x); 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 12 (Bits)/Counting Bits.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int count(int n) 4 | { 5 | int c = 0; 6 | while(n) 7 | { 8 | n = n&(n-1); 9 | c++; 10 | } 11 | return c; 12 | } 13 | vector countBits(int num) { 14 | vector res; 15 | for(int i = 0; i <= num; i++) 16 | { 17 | res.push_back(count(i)); 18 | } 19 | return res; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 12 (Bits)/Most Significant Bit.cpp: -------------------------------------------------------------------------------- 1 | 2 | int setBitNumber(int n) 3 | { 4 | 5 | // To find the position 6 | // of the most significant 7 | // set bit 8 | int k = (int)(log2(n)); 9 | 10 | // To return the the value 11 | // of the number with set 12 | // bit at k-th position 13 | return 1 << k; 14 | } 15 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 12 (Bits)/Power of 2.cpp: -------------------------------------------------------------------------------- 1 | 2 | class Solution { 3 | public: 4 | bool isPowerOfTwo(int n) { 5 | if(n <= 0) 6 | return false; 7 | int x = n-1; 8 | int res = (n&x); 9 | if(res == 0) 10 | return true; 11 | else 12 | return false; 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 12 (Bits)/Subsets.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector> subsets(vector& nums) { 4 | int n = nums.size(); 5 | int x = pow(2,n); 6 | vector> res; 7 | for(int i = 0; i < x; i++) 8 | { 9 | vector temp; 10 | for(int j = 0; j < n; j++) 11 | { 12 | if(i&(1<> levelOrder(TreeNode* root) { 6 | vector> res; 7 | if(!root) return res; 8 | 9 | queue q; 10 | q.push(root); 11 | q.push(NULL); // a NULL denotes the end of a particular level. Next level of BFS starts after a NULL 12 | 13 | vector ans; 14 | while(!q.empty()){ 15 | TreeNode* curr = q.front(); q.pop(); 16 | if(curr == NULL){ // current level over 17 | res.emplace_back(ans); //push particular lvl vector to ans 18 | ans.resize(0); // same as ans.clear() 19 | if(q.size() > 0) q.push(NULL); // if next lvl elements are there add a NULL behind them 20 | } 21 | else { 22 | ans.emplace_back(curr->val); // emplace_back is a faster alternative to push_back 23 | if(curr->left) q.push(curr->left); 24 | if(curr->right) q.push(curr->right); 25 | } 26 | } 27 | 28 | return res; 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 13 (Stacks and Queues)/Balanced Parenthesis.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | bool isValid(string s) { 4 | if(s.size() % 2 != 0) return false; 5 | stack stk; 6 | for(auto it: s){ 7 | if(it == '(' || it == '{' || it == '[') stk.push(it); 8 | else if(it == ')' && !stk.empty() && stk.top() == '(') stk.pop(); 9 | else if(it == '}' && !stk.empty() && stk.top() == '{') stk.pop(); 10 | else if(it == ']' && !stk.empty() && stk.top() == '[') stk.pop(); 11 | else return false; 12 | } 13 | 14 | return stk.empty(); 15 | } 16 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 13 (Stacks and Queues)/Implement Queue using Stack.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class MyQueue { 4 | public: 5 | /** Initialize your data structure here. */ 6 | stack s1, s2; 7 | MyQueue() { 8 | 9 | } 10 | 11 | /** Push element x to the back of queue. */ 12 | void push(int x) { 13 | s1.push(x); 14 | } 15 | 16 | /** Removes the element from in front of queue and returns that element. */ 17 | int pop() { 18 | while(s1.size()){ 19 | s2.push(s1.top()); 20 | s1.pop(); 21 | } 22 | int temp = s2.top(); s2.pop(); 23 | while(s2.size()){ 24 | s1.push(s2.top()); s2.pop(); 25 | } 26 | return temp; 27 | } 28 | 29 | /** Get the front element. */ 30 | int peek() { 31 | while(s1.size()){ 32 | s2.push(s1.top()); 33 | s1.pop(); 34 | } 35 | int temp = s2.top(); 36 | while(s2.size()){ 37 | s1.push(s2.top()); s2.pop(); 38 | } 39 | return temp; 40 | } 41 | 42 | /** Returns whether the queue is empty. */ 43 | bool empty() { 44 | return s1.empty() && s2.empty(); 45 | } 46 | 47 | }; 48 | 49 | /** 50 | * Your MyQueue object will be instantiated and called as such: 51 | * MyQueue* obj = new MyQueue(); 52 | * obj->push(x); 53 | * int param_2 = obj->pop(); 54 | * int param_3 = obj->peek(); 55 | * bool param_4 = obj->empty(); 56 | */ 57 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 13 (Stacks and Queues)/Implement Stack using Queue.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class MyStack { 4 | public: 5 | /** Initialize your data structure here. */ 6 | queue q; 7 | MyStack() { 8 | // we can do this with only 1 Queue. 2 Not needed 9 | } 10 | 11 | /** Push element x onto stack. */ 12 | void push(int x) { 13 | int len = q.size(); 14 | q.push(x); 15 | for(int i = 0; i != len; i++){ 16 | q.push(q.front()); 17 | q.pop(); 18 | // basically add the new element, then pop off all the elements before it and append then behind the new ele. So new ele is in the front of Q i.e. top of "stack" 19 | } 20 | } 21 | 22 | /** Removes the element on top of the stack and returns that element. */ 23 | int pop() { 24 | int temp = q.front(); 25 | q.pop(); 26 | return temp; 27 | } 28 | 29 | /** Get the top element. */ 30 | int top() { 31 | return q.front(); 32 | } 33 | 34 | /** Returns whether the stack is empty. */ 35 | bool empty() { 36 | return q.empty(); 37 | } 38 | }; 39 | 40 | /** 41 | * Your MyStack object will be instantiated and called as such: 42 | * MyStack* obj = new MyStack(); 43 | * obj->push(x); 44 | * int param_2 = obj->pop(); 45 | * int param_3 = obj->top(); 46 | * bool param_4 = obj->empty(); 47 | */ 48 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 13 (Stacks and Queues)/Next Greater Element.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | vector nextGreaterElement(vector& nums1, vector& nums2) { 4 | unordered_map m; 5 | stack s; 6 | for(int it: nums2){ 7 | while(!s.empty() && it > s.top()){ // keep checking till it < top element 8 | m[s.top()] = it; // map element and its next greater ele 9 | s.pop(); 10 | } 11 | s.push(it); 12 | } 13 | 14 | for(int &it: nums1){ 15 | // if the element key exists (checked w count) then replace "it" with greater ele. Else -1 16 | it = m.count(it) ? m[it] : -1; 17 | } 18 | return nums1; 19 | } 20 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 14/Implement Min Stack.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | /** initialize your data structure here. */ 4 | stack> stk; 5 | 6 | MinStack() { 7 | 8 | } 9 | 10 | void push(int val) { 11 | int minVal = INT_MAX; 12 | if(stk.empty()){ 13 | minVal = val; 14 | } else { 15 | minVal = min(stk.top().second, val); 16 | } 17 | 18 | stk.push({val, minVal}); 19 | } 20 | 21 | void pop() { 22 | stk.pop(); 23 | } 24 | 25 | int top() { 26 | return stk.top().first; 27 | } 28 | 29 | int getMin() { 30 | return stk.top().second; 31 | } 32 | 33 | //Sid's solution 34 | /*returns min element from stack*/ 35 | int _stack :: getMin() 36 | { 37 | //Your code here 38 | if(s.empty()) 39 | return -1; 40 | else 41 | return minEle; 42 | } 43 | 44 | /*returns poped element from stack*/ 45 | int _stack ::pop() 46 | { 47 | //Your code here 48 | if(s.empty()) 49 | return -1; 50 | else 51 | { 52 | 53 | if(s.top() >= minEle) 54 | { 55 | int x = s.top(); 56 | s.pop(); 57 | return x; 58 | } 59 | else 60 | { 61 | int x = minEle; 62 | minEle = 2*x - s.top(); 63 | s.pop(); 64 | return x; 65 | } 66 | } 67 | } 68 | 69 | /*push element x into the stack*/ 70 | void _stack::push(int x) 71 | { 72 | //Your code here 73 | if(s.empty()) 74 | { 75 | minEle = x; 76 | s.push(x); 77 | } 78 | else if(x >= minEle) 79 | { 80 | s.push(x); 81 | } 82 | else 83 | { 84 | s.push(2*x-minEle); 85 | minEle = x; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 14/LRU Cache (Hard)(VVIP).cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class LRUCache { 4 | public: 5 | // To add and remove ele in constant time O(1) we use linked list and not array as in array, 6 | // to shift after deletion is O(n) but not needed in LL ( head, tail ptr) 7 | 8 | // To check if element is already in cache, use hashmap (store address and value) 9 | // Hence, traversal also O(1) and not o(n) 10 | int capacity; 11 | list recent; // (front) MRU......LRU (back) has the element values 12 | unordered_map::iterator> pos; // key->iterator 13 | unordered_map cache; //key->value. key is the memory of the element value 14 | 15 | void use(int key){ 16 | if(pos.find(key) != pos.end()){ 17 | // key exists. 18 | recent.erase(pos[key]); 19 | } else if(recent.size() >= capacity){ 20 | //remove LRU 21 | int old = recent.back(); 22 | recent.pop_back(); 23 | cache.erase(old); pos.erase(old); 24 | } 25 | // add new ele to front (MRU) and make it front 26 | // no need to shift back all elements before adding new ele as we are not using array 27 | recent.push_front(key); 28 | pos[key] = recent.begin(); 29 | } 30 | 31 | LRUCache(int capacity) { // runs when initialized 32 | this->capacity = capacity; 33 | } 34 | 35 | int get(int key) { 36 | if(cache.find(key) != cache.end()){ 37 | use(key); 38 | return cache[key]; 39 | } 40 | return -1; 41 | } 42 | 43 | void put(int key, int value) { 44 | use(key); 45 | cache[key] = value; 46 | } 47 | }; 48 | 49 | /** 50 | * Your LRUCache object will be instantiated and called as such: 51 | * LRUCache* obj = new LRUCache(capacity); 52 | * int param_1 = obj->get(key); 53 | * obj->put(key,value); 54 | */ 55 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 14/Next Smaller Element.cpp: -------------------------------------------------------------------------------- 1 | // Sid 2 | 3 | #include 4 | using namespace std; 5 | int main() 6 | { 7 | stack s; 8 | vector x; 9 | int n; 10 | cin >> n; 11 | for(int i = 0; i < n; i++) 12 | { 13 | int a; 14 | cin >> a; 15 | x.push_back(a); 16 | } 17 | int nse[1000]; 18 | for(int i = 0; i < n; i++) 19 | { 20 | if(s.empty()) 21 | { 22 | s.push(i); 23 | } 24 | else 25 | { 26 | if(x[s.top()] > x[i]) 27 | { 28 | while(!s.empty() && x[s.top()] > x[i]) 29 | { 30 | nse[s.top()] = x[i]; 31 | s.pop(); 32 | } 33 | s.push(i); 34 | } 35 | else 36 | { 37 | s.push(i); 38 | } 39 | } 40 | } 41 | while(!s.empty()) 42 | { 43 | nse[s.top()] = -1; 44 | s.pop(); 45 | } 46 | for(int i = 0; i < n; i++) 47 | cout << nse[i] << " "; 48 | } 49 | 50 | // Hari 51 | 52 | #include 53 | using namespace std; 54 | 55 | int main() { 56 | int n; 57 | vector a; 58 | 59 | cin >> n; 60 | 61 | for(int i = 0; i> temp; 64 | a.push_back(temp); 65 | } 66 | 67 | int NSE[1000]; 68 | stack s; 69 | 70 | for(int i = 0; i a[i]){ 75 | while(!s.empty() && a[s.top()] > a[i]){ 76 | NSE[s.top()] = a[i]; 77 | s.pop(); 78 | } 79 | s.push(i); 80 | } 81 | else s.push(i); 82 | } 83 | 84 | while(!s.empty()){ 85 | // check if remaining elements exist and for them in NSE assign -1 86 | NSE[s.top()] = -1; 87 | s.pop(); 88 | } 89 | 90 | for(int i = 0; i maxSlidingWindow(vector& nums, int k) { 4 | deque dq; 5 | vector ans; 6 | 7 | for(int curr = 0; curr dq's top, keep pop-ing it. All elements in dq < nums[curr] are removed as they have o chance of getting selected in window range 11 | while(!dq.empty() && nums[dq.back()] < nums[curr]) dq.pop_back(); 12 | // now we add the nums[curr] to dq 13 | dq.push_back(curr); 14 | // the front of dq has the largest number in (curr-k, curr) window 15 | if(curr - k + 1 >= 0) ans.emplace_back(nums[dq.front()]); 16 | } 17 | return ans; 18 | } 19 | 20 | 21 | //Sid's solution 22 | 23 | 24 | class Solution { 25 | public: 26 | vector maxSlidingWindow(vector& nums, int k) { 27 | //first find the next greater element 28 | //in a window if the next greater element of an element is outside the window then tha will be the maximum element in the window. If the next greater element 29 | //exists in the window then go to the next greater element and check it again, then mark it the greatest. 30 | int nge[100000]; 31 | stack s; 32 | int n = nums.size(); 33 | for(int i = 0; i < n; i++) 34 | { 35 | if(s.empty()) 36 | { 37 | s.push(i); 38 | } 39 | else 40 | { 41 | if(nums[i] > nums[s.top()]) 42 | { 43 | while(!s.empty() && nums[i] > nums[s.top()]) 44 | { 45 | nge[s.top()] = i; 46 | s.pop(); 47 | } 48 | s.push(i); 49 | } 50 | else 51 | { 52 | s.push(i); 53 | } 54 | } 55 | } 56 | while(!s.empty()) 57 | { 58 | nge[s.top()] = n; 59 | s.pop(); 60 | } 61 | vector res; 62 | int j = 0; 63 | for(int i = 0; i <= n-k; i++) 64 | { 65 | if(j < i) 66 | { 67 | j = i; 68 | } 69 | while(nge[j] < i+k) 70 | { 71 | j = nge[j]; 72 | } 73 | res.push_back(nums[j]); 74 | } 75 | return res; 76 | } 77 | }; 78 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 15 (Strings)/Implement ATOI and STRSTR.cpp: -------------------------------------------------------------------------------- 1 | // ATOI (Hari) Not satisfying stupid testcases on LC. Normal tc are fine 2 | 3 | int myAtoi(string s) { 4 | int i = 0; 5 | int minVal = -2147483648; 6 | int maxVal = 2147483647; 7 | vector finalNum; 8 | for(; i 9223372036854775807) break; 30 | long long int temp = finalNum[j]*pow(10,N - j - 1); 31 | finalAns += temp; 32 | } 33 | if(sign){ 34 | finalAns = -finalAns; 35 | } 36 | if(finalAns < minVal) return minVal; 37 | if(finalAns > maxVal) return maxVal; 38 | return finalAns; 39 | } 40 | 41 | // not my soln 42 | 43 | class Solution { 44 | public: 45 | int myAtoi(string str) { 46 | if (str.empty()) return 0; 47 | int i = 0, sign = 1; 48 | while (i + 1 < str.size() && isspace(str[i])) ++i; 49 | long res = 0; 50 | if (str[i] == '-' || str[i] == '+') sign = 44 - str[i++]; 51 | while (i < str.size()) { 52 | if (isdigit(str[i])) res = 10 * res + str[i++] - '0'; 53 | else return res * sign; 54 | if (res > INT_MAX) return sign == -1 ? INT_MIN : INT_MAX; 55 | } 56 | return res * sign; 57 | } 58 | }; 59 | 60 | // STRSTR (Sid) 61 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 15 (Strings)/Longest Common Prefix.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution { 4 | public: 5 | string helper(string s1, string s2){ 6 | int t1 = 0, t2 = 0; 7 | while(t1 < s1.size() && t2 < s2.size()){ 8 | if(s1[t1] == s2[t2]) { 9 | t1++; 10 | t2++; 11 | } else break; 12 | } 13 | return s1.substr(0, t1); 14 | } 15 | 16 | string longestCommonPrefix(vector& strs) { 17 | if(strs.size() == 1) return strs[0]; 18 | // find the longest common prefix for first 2 strings in vector 19 | string res = helper(strs[0], strs[1]); 20 | // we get the LCP 21 | // check if this LCP exists within the rest of the strings in vector 22 | for(int i = 2; i& strs) { 45 | string res; 46 | if(strs.size() == 1) 47 | return strs[0]; 48 | res = helper(strs[0], strs[1]); 49 | for(int i = 2; i < strs.size(); i++) 50 | { 51 | res = helper(res, strs[i]); 52 | } 53 | return res; 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 15 (Strings)/Longest Palindrome substring.cpp: -------------------------------------------------------------------------------- 1 | // Sid 2 | class Solution { 3 | public: 4 | string longestPalindrome(string s) { 5 | int maxLen = 1; 6 | int n = s.length(); 7 | string res; 8 | int startInd = 0; 9 | //for each index, check if even or odd length palindrome can be formed from that character given the character is the pivot of the palindrome 10 | for(int i = 0; i < n; i++) 11 | { 12 | //odd palindrome 13 | int l = i - 1; 14 | int r = i + 1; 15 | while(l >= 0 && r < n && s[l] == s[r]) 16 | { 17 | if(r - l + 1 > maxLen) 18 | { 19 | maxLen = r - l + 1; 20 | startInd = l; 21 | } 22 | l--; 23 | r++; 24 | } 25 | //even palindrome 26 | l = i; 27 | r = i+1; 28 | while(l >= 0 && r < n && s[l] == s[r]) 29 | { 30 | if(r - l + 1 > maxLen) 31 | { 32 | maxLen = r - l + 1; 33 | startInd = l; 34 | } 35 | l--; 36 | r++; 37 | } 38 | 39 | } 40 | return s.substr(startInd, maxLen); 41 | } 42 | }; 43 | 44 | // Hari 45 | 46 | string longestPalindrome(string s) { 47 | int N = s.size(); 48 | int maxLen = 1; // as a single letter is also a palindrome 49 | int start = 0; // assigning the start of the longest palindrome 50 | 51 | for(int i = 0; i= 0 && r < N && s[l] == s[r]){ 56 | if(r - l + 1 > maxLen){ 57 | start = l; 58 | maxLen = r - l + 1; 59 | } 60 | l-- ; r++; 61 | } 62 | 63 | // check for even size palindrome from this index 64 | l = i; 65 | r = i + 1; 66 | while(l >= 0 && r < N && s[l] == s[r]){ 67 | if(r - l + 1 > maxLen){ 68 | start = l; 69 | maxLen = r - l + 1; 70 | } 71 | l-- ; r++; 72 | } 73 | } 74 | 75 | return s.substr(start, maxLen); 76 | } 77 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 15 (Strings)/Reverse words in String.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | string reverseWords(string s) { 4 | string ans = ""; 5 | for(int i = 0; i 0) ans = " " + ans; 11 | string wordFormed = s.substr(l, i-l); 12 | ans = wordFormed + ans; 13 | } 14 | return ans; 15 | } 16 | 17 | //Sid 18 | 19 | class Solution { 20 | public: 21 | string reverseWords(string s) { 22 | int i, j; 23 | i = 0, j = 0; 24 | while(i < s.length() && j < s.length()) 25 | { 26 | if(s[i] == ' ') 27 | { 28 | while(i < s.length()-1 && s[i] == s[i+1]) 29 | i++; 30 | s[j] = s[i]; 31 | j++; 32 | i++; 33 | } 34 | else 35 | { 36 | s[j] = s[i]; 37 | j++; 38 | i++; 39 | } 40 | } 41 | s = s.substr(0,j); 42 | if(s[0] == ' ') 43 | { 44 | s = s.substr(1, s.length()-1); 45 | } 46 | if(s[s.length()-1] == ' ') 47 | { 48 | s = s.substr(0, s.length() - 1); 49 | } 50 | reverse(s.begin(), s.end()); 51 | i = 0; 52 | j = 0; 53 | for(i = 0; i < s.length(); i++) 54 | { 55 | while(i < s.length() && s[i] != ' ') 56 | { 57 | i++; 58 | } 59 | int r = i - 1; 60 | i++; 61 | int l = j; 62 | while(l <= r) 63 | { 64 | swap(s[l], s[r]); 65 | l++; 66 | r--; 67 | } 68 | j = i; 69 | } 70 | return s; 71 | } 72 | }; 73 | 74 | 75 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 16 (Strings)/Check for anagrams.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | bool isAnagram(string s, string t) { 4 | int freq[26] = {0}; 5 | for(int i = 0; i< s.size(); i++){ 6 | freq[s[i] - 'a']++; 7 | } 8 | 9 | for(int i = 0; i num2) return 1; 18 | // if both equal 19 | i++; j++; 20 | } 21 | return 0; 22 | } 23 | 24 | //Sid's solution 25 | 26 | class Solution { 27 | public: 28 | 29 | int compareVersion(string version1, string version2) { 30 | int i = 0, j = 0; 31 | int n = version1.length(); 32 | int m = version2.length(); 33 | vector v1, v2; 34 | string s; 35 | while(i < n) 36 | { 37 | if(version1[i] == '.') 38 | { 39 | v1.push_back(s); 40 | s.clear(); 41 | } 42 | else 43 | { 44 | s.push_back(version1[i]); 45 | } 46 | i++; 47 | } 48 | v1.push_back(s); 49 | s.clear(); 50 | while(j < m) 51 | { 52 | if(version2[j] == '.') 53 | { 54 | v2.push_back(s); 55 | s.clear(); 56 | } 57 | else 58 | { 59 | s.push_back(version2[j]); 60 | } 61 | j++; 62 | } 63 | v2.push_back(s); 64 | s.clear(); 65 | int ptr1 = 0, ptr2 = 0; 66 | while(ptr1 < v1.size() && ptr2 < v2.size()) 67 | { 68 | int num1 = stoi(v1[ptr1]); 69 | int num2 = stoi(v2[ptr2]); 70 | if(num1 == num2) 71 | { 72 | ptr1++; 73 | ptr2++; 74 | } 75 | else if(num1 > num2) 76 | return 1; 77 | else 78 | return -1; 79 | } 80 | while(ptr1 < v1.size()) 81 | { 82 | int num1 = stoi(v1[ptr1]); 83 | if(num1 > 0) 84 | return 1; 85 | ptr1++; 86 | } 87 | while(ptr2 < v2.size()) 88 | { 89 | int num2 = stoi(v2[ptr2]); 90 | if(num2 > 0) 91 | return -1; 92 | ptr2++; 93 | } 94 | return 0; 95 | } 96 | }; 97 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 16 (Strings)/Count and Say.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | // Iterative method 3 | 4 | string countAndSay(int A) { 5 | if(A == 0) return ""; 6 | if(A == 1) return "1"; 7 | 8 | string ans = "1"; 9 | string temp = ""; 10 | 11 | while(A > 1){ 12 | int N = ans.size(); 13 | for(int i = 0; i + '0' but char to int -> - '0' 21 | temp.push_back((char)(ans[i])); 22 | } 23 | ans = temp; 24 | temp = ""; 25 | A--; 26 | } 27 | return ans; 28 | } 29 | 30 | //Sid 31 | //Recursive solution 32 | class Solution { 33 | public: 34 | string helper(int cur, string &s, int n) 35 | { 36 | if(cur > n) 37 | return s; 38 | else if(cur == 1) 39 | { 40 | s.push_back('1'); 41 | return helper(cur+1, s, n); 42 | } 43 | else 44 | { 45 | string s1; 46 | for(int i = 0; i < s.length(); i++) 47 | { 48 | int c = 1; 49 | while(i < s.length()-1 && s[i] == s[i+1]) 50 | { 51 | i++; 52 | c++; 53 | } 54 | s1.push_back((char)(c+'0')); 55 | s1.push_back((char)(s[i])); 56 | } 57 | return helper(cur+1, s1, n); 58 | } 59 | } 60 | string countAndSay(int n) { 61 | string s; 62 | return helper(1, s, n); 63 | } 64 | }; 65 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 17 (Binary Tree)/Bottom View Of Binary Tree.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | // Refer Top view before this. Exact same method. There, we add the first element that is in a level and then don't change it. Here, we keep updating elements in each lvl 4 | // as we traverse..so at each lvl the last element that came at that level is present 5 | 6 | //Function to return a list containing the bottom view of the given tree. 7 | vector bottomView(Node *root) 8 | { 9 | // last element you get for a particular vertical level is the element u see from bottom 10 | map m; // level and corresp element 11 | /* 12 | -2 -1 0 1 2 are the vertical levels. 13 | */ 14 | queue> q; // Element and corresp. height 15 | vector res; 16 | if(!root) return res; 17 | q.push({root, 0}); 18 | while(!q.empty()){ 19 | Node* curr = q.front().first; 20 | int currht = q.front().second; 21 | q.pop(); 22 | m[currht] = curr->data; // if val for this currht already exists, continue 23 | if(curr->left) q.push({curr->left, currht-1}); 24 | if(curr->right) q.push({curr->right, currht+1}); 25 | } 26 | // our map m has all the elements visible from top at each vertical level 27 | for(auto t: m){ 28 | res.push_back(t.second); 29 | } 30 | return res; 31 | } 32 | 33 | // Sid 34 | //Function to return a list containing the bottom view of the given tree. 35 | vector bottomView(Node *root) 36 | { 37 | vector res; 38 | map mp; 39 | queue q1; 40 | queue q2; 41 | q1.push(root); 42 | q2.push(0); 43 | while(!q1.empty() && !q2.empty()) 44 | { 45 | Node *cur = q1.front(); 46 | int dist = q2.front(); 47 | q1.pop(); 48 | q2.pop(); 49 | mp[dist] = cur->data; 50 | if(cur->left != NULL) 51 | { 52 | q1.push(cur->left); 53 | q2.push(dist-1); 54 | } 55 | if(cur->right != NULL) 56 | { 57 | q1.push(cur->right); 58 | q2.push(dist+1); 59 | } 60 | } 61 | map:: iterator it; 62 | for(it = mp.begin(); it != mp.end(); it++) 63 | { 64 | res.push_back(it->second); 65 | } 66 | return res; 67 | } 68 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 17 (Binary Tree)/Inorder Iterative.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | vector inorderTraversal(TreeNode* root) { 15 | stack s; 16 | vector res; 17 | TreeNode* x = root; 18 | while(x != NULL || s.size() > 0) 19 | { 20 | while(x != NULL) 21 | { 22 | s.push(x); 23 | x = x->left; 24 | } 25 | x = s.top(); 26 | s.pop(); 27 | res.push_back(x->val); 28 | x = x->right; 29 | } 30 | return res; 31 | } 32 | }; -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 17 (Binary Tree)/Inorder Recursive.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | void helper(TreeNode *root, vector &res) 15 | { 16 | if(root == NULL) 17 | { 18 | return; 19 | } 20 | helper(root->left, res); 21 | res.push_back(root->val); 22 | helper(root->right, res); 23 | } 24 | vector inorderTraversal(TreeNode* root) { 25 | vector res; 26 | helper(root, res); 27 | return res; 28 | } 29 | }; -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 17 (Binary Tree)/Inorder Traversal(both).cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | void helper(TreeNode* root, vector &res){ // Recursive 4 | if(root == nullptr) return; 5 | else { 6 | helper(root->left, res); 7 | res.push_back(root->val); 8 | helper(root->right, res); 9 | } 10 | } 11 | 12 | 13 | vector inorderTraversal(TreeNode* root) { 14 | // Iterative 15 | // stack s; 16 | // vector res; 17 | // TreeNode* curr = root; 18 | 19 | // while(curr != NULL || !s.empty()){ 20 | // while(curr != NULL){ 21 | // s.push(curr); 22 | // curr = curr->left; 23 | // } 24 | // // when NULL is reached 25 | // curr = s.top(); 26 | // res.emplace_back(curr->val); 27 | // curr = curr->right; 28 | // s.pop(); 29 | // } 30 | // return res; 31 | 32 | // Recursive 33 | vector res; 34 | helper(root, res); 35 | return res; 36 | } 37 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 17 (Binary Tree)/Left View Of Binary Tree.cpp: -------------------------------------------------------------------------------- 1 | //Sid solution 2 | void helper(Node *root, int level, int &maxLevel, vector &res) 3 | { 4 | if(root == NULL) 5 | return; 6 | if(level > maxLevel) 7 | { 8 | maxLevel = level; 9 | res.push_back(root->data); 10 | } 11 | helper(root->left, level+1, maxLevel, res); 12 | helper(root->right, level+1, maxLevel, res); 13 | } 14 | vector leftView(Node *root) 15 | { 16 | vector res; 17 | int level = 0, maxLevel = INT_MIN; 18 | helper(root, level, maxLevel, res); 19 | return res; 20 | } 21 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 17 (Binary Tree)/Postorder (both).cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | // void helper(TreeNode* root, vector &res){ // Recursive 4 | // if(root == nullptr) return; 5 | // helper(root->left, res); 6 | // helper(root->right, res); 7 | // res.push_back(root->val); 8 | // } 9 | 10 | vector postorderTraversal(TreeNode* root) { 11 | // vector res; // Recursive 12 | // helper(root, res); 13 | // return res; 14 | 15 | // Iterative 16 | stack s; 17 | vector res; 18 | if(root == nullptr) return res; 19 | s.push(root); 20 | while(!s.empty()){ 21 | TreeNode* curr = s.top(); 22 | res.push_back(curr->val); s.pop(); 23 | // In Postorder it is left->right->root. The reverse of this is root->right->left...which is a partial reverse of Preorder(root->left->right) 24 | // So in preorder we pushed right to stack and then left. Here, do the opposite 25 | if(curr->left) s.push(curr->left); 26 | if(curr->right) s.push(curr->right); 27 | } 28 | reverse(res.begin(), res.end()); 29 | return res; 30 | } 31 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 17 (Binary Tree)/Postorder Iterative.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | vector helper(TreeNode *root) 15 | { 16 | vector res; 17 | if(root == NULL) 18 | return res; 19 | stack s; 20 | s.push(root); 21 | while(s.size() > 0) 22 | { 23 | TreeNode *x = s.top(); 24 | res.push_back(x->val); 25 | s.pop(); 26 | if(x->left != NULL) 27 | s.push(x->left); 28 | if(x->right != NULL) 29 | s.push(x->right); 30 | } 31 | reverse(res.begin(), res.end()); 32 | return res; 33 | } 34 | vector postorderTraversal(TreeNode* root) { 35 | vector res = helper(root); 36 | return res; 37 | } 38 | }; -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 17 (Binary Tree)/Postorder Recursive.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | void helper(TreeNode *root, vector &res) 15 | { 16 | if(root == NULL) 17 | return; 18 | helper(root->left, res); 19 | helper(root->right, res); 20 | res.push_back(root->val); 21 | } 22 | vector postorderTraversal(TreeNode* root) { 23 | vector res; 24 | helper(root, res); 25 | return res; 26 | } 27 | }; -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 17 (Binary Tree)/Preorder (both).cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | // void helper(TreeNode* root, vector &res){ //Recursive 4 | // if(root == nullptr) return; 5 | // res.push_back(root->val); 6 | // helper(root->left, res); 7 | // helper(root->right, res); 8 | // } 9 | vector preorderTraversal(TreeNode* root) { 10 | // Recursive 11 | // vector res; 12 | // helper(root, res); 13 | // return res; 14 | 15 | //Iterative 16 | stack s; 17 | vector res; 18 | if(root == nullptr) return res; 19 | s.push(root); 20 | while(!s.empty()){ 21 | TreeNode* curr = s.top(); 22 | res.push_back(curr->val); 23 | s.pop(); 24 | // Push right first then left as stack is LIFO 25 | if(curr->right) s.push(curr->right); 26 | if(curr->left) s.push(curr->left); 27 | } 28 | return res; 29 | } 30 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 17 (Binary Tree)/Preorder Iterative.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | vector preorderTraversal(TreeNode* root) { 15 | vector res; 16 | if(root == NULL) 17 | { 18 | return res; 19 | } 20 | 21 | stack s; 22 | s.push(root); 23 | while(s.size() > 0) 24 | { 25 | TreeNode *cur = s.top(); 26 | res.push_back(cur->val); 27 | s.pop(); 28 | if(cur->right != NULL) 29 | s.push(cur->right); 30 | if(cur->left != NULL) 31 | s.push(cur->left); 32 | } 33 | return res; 34 | } 35 | }; -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 17 (Binary Tree)/Preorder Recursive.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | void helper(TreeNode *root, vector &res) 15 | { 16 | if(root == NULL) 17 | return; 18 | res.push_back(root->val); 19 | helper(root->left, res); 20 | helper(root->right, res); 21 | } 22 | vector preorderTraversal(TreeNode* root) { 23 | vector res; 24 | helper(root, res); 25 | return res; 26 | } 27 | }; -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 17 (Binary Tree)/Right View of Binary Tree.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | vector rightSideView(TreeNode* root) { 4 | vector res; 5 | queue q; 6 | if(root == nullptr) return res; 7 | q.push(root); 8 | while(!q.empty()){ 9 | int N = q.size(); 10 | for(int i = 1; i<=N; i++){ 11 | TreeNode* curr = q.front(); q.pop(); 12 | if(i == N) res.push_back(curr->val); 13 | if(curr->left) q.push(curr->left); 14 | if(curr->right) q.push(curr->right); 15 | } 16 | } 17 | return res; 18 | } 19 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 17 (Binary Tree)/Top View Of Binary Tree.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution 4 | { 5 | public: 6 | //Function to return a list of nodes visible from the top view 7 | //from left to right in Binary Tree. 8 | vector topView(Node *root) 9 | { 10 | // first element you get for a particular vertical level is the element u see from top 11 | map m; // level and corresp element 12 | /* 13 | -2 -1 0 1 2 are the vertical levels. 14 | If element is in a level and current val for that level is 0, then add this element to 15 | that level. Else, that element is not visible at that level. So, continue 16 | */ 17 | queue> q; // Element and corresp. height 18 | vector res; 19 | if(!root) return res; 20 | q.push({root, 0}); 21 | while(!q.empty()){ 22 | Node* curr = q.front().first; 23 | int currht = q.front().second; 24 | q.pop(); 25 | if(!m[currht]) m[currht] = curr->data; // if val for this currht already exists, continue 26 | if(curr->left) q.push({curr->left, currht-1}); 27 | if(curr->right) q.push({curr->right, currht+1}); 28 | } 29 | // our map m has all the elements visible from top at each vertical level 30 | for(auto t: m){ 31 | res.push_back(t.second); 32 | } 33 | return res; 34 | 35 | } 36 | 37 | }; 38 | 39 | // Sid 40 | 41 | class Solution 42 | { 43 | public: 44 | //Function to return a list of nodes visible from the top view 45 | //from left to right in Binary Tree. 46 | vector topView(Node *root) 47 | { 48 | map mp; 49 | //we ll be doing level order traversal and updating the horizontal distances from the root 50 | queue q1; // queue to store the horizontal distances of nodes from root 51 | queue q2;//queue to store the nodes from the root 52 | q2.push(root); 53 | q1.push(0); 54 | while(!q1.empty() && !q2.empty()) 55 | { 56 | Node *cur = q2.front(); 57 | int dist = q1.front(); 58 | q1.pop(); 59 | q2.pop(); 60 | if(mp.count(dist) == 0) 61 | { 62 | //if the distance hasnt been encountered yet then add it as it means it's the first occurrence 63 | mp[dist] = cur->data; 64 | } 65 | if(cur->left != NULL) 66 | { 67 | q2.push(cur->left); 68 | q1.push(dist-1); 69 | } 70 | if(cur->right != NULL) 71 | { 72 | q2.push(cur->right); 73 | q1.push(dist+1); 74 | } 75 | 76 | } 77 | vector res; 78 | map::iterator it; 79 | for(it = mp.begin(); it != mp.end(); it++) 80 | { 81 | res.push_back(it->second); 82 | } 83 | return res; 84 | } 85 | 86 | }; 87 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 18 (Binary Tree)/Check if trees identical.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution { 4 | public: 5 | bool isSameTree(TreeNode* p, TreeNode* q) { 6 | // check if nodes are none or not, then if value matches or not. If value matches, check if they are in the same subtree / position in their resp. tree 7 | 8 | // base cases 9 | if(!p && !q) return true; // both nullptr then valid 10 | else if(!p || !q) return false; // only one of them is null 11 | else if(p->val != q->val) return false; // nodes exist but diff values 12 | else return isSameTree(p->left, q->left) && isSameTree(p->right, q->right); // nodes are the same. Now compare their subtrees and if any one of them don't match then invalid 13 | } 14 | }; 15 | 16 | //Sid 17 | bool isSameTree(TreeNode* p, TreeNode* q) { 18 | if(p == NULL && q == NULL) 19 | return true; 20 | else if(p == NULL || q == NULL) 21 | return false; 22 | bool l = isSameTree(p->left, q->left); 23 | bool r = isSameTree(p->right, q->right); 24 | if(p->val == q->val && l && r) 25 | return true; 26 | return false; 27 | } 28 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 18 (Binary Tree)/Diameter of tree.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | int helper(TreeNode* curr, int &d){ 4 | if(curr == nullptr) return 0; 5 | 6 | int left = helper(curr->left, d); 7 | int right = helper(curr->right, d); 8 | 9 | d = max(d, left+right); // keeps check of maxDia for each node and at the end it will have maxDia for whole tree 10 | return max(left, right) + 1; // for next lvl (see finding maxDepth qn) 11 | } 12 | 13 | int diameterOfBinaryTree(TreeNode* root) { 14 | // In finding ht of tree, we just calc max ht for each node by finding max depth of its left and right node + 1 (curr node) and return this val for the next level 15 | // For dia, its very similar to this. Max dia = max(dia, left+right) 16 | int maxDia = 0; 17 | helper(root, maxDia); 18 | return maxDia; 19 | 20 | } 21 | 22 | //Sid 23 | int diameter(TreeNode* root, int &h) 24 | { 25 | if(root == NULL) 26 | return 0; 27 | int lh = 0, rh = 0; 28 | int ld = diameter(root->left, lh); 29 | int rd = diameter(root->right, rh); 30 | h = max(lh, rh) + 1; 31 | return max(lh+rh, max(ld, rd)); 32 | } 33 | int diameterOfBinaryTree(TreeNode* root) { 34 | int h = 0; 35 | return diameter(root, h); 36 | } 37 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 18 (Binary Tree)/Height balanced Check.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | // Check if BTree is height balanced or not 4 | 5 | class Solution { 6 | public: 7 | int htBalChk = 1; 8 | int helper(TreeNode* curr){ 9 | if(!curr) return 0; 10 | int left = helper(curr->left); 11 | int right = helper(curr->right); 12 | if(abs(left - right) > 1) htBalChk = 0; 13 | return max(left, right) + 1; // next level 14 | } 15 | 16 | bool isBalanced(TreeNode* root) { 17 | htBalChk = 1; // assume its ht balanced initially 18 | helper(root); 19 | return htBalChk; 20 | } 21 | }; 22 | 23 | //Sid 24 | bool helper(TreeNode *root, int &h) 25 | { 26 | if(root == NULL) 27 | { 28 | h = 0; 29 | return true; 30 | } 31 | int lh = 0, rh = 0; 32 | bool l = helper(root->left, lh); 33 | bool r = helper(root->right, rh); 34 | h = max(lh, rh) + 1; 35 | if(l && r && abs(lh-rh) <= 1) 36 | return true; 37 | else 38 | return false; 39 | } 40 | bool isBalanced(TreeNode* root) { 41 | int height = 0; 42 | return helper(root, height); 43 | } 44 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 18 (Binary Tree)/Height of Binary Tree.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | int maxDepth(TreeNode* root) { 4 | // if(root == nullptr) return 0; //base case when we reach a leaf 5 | 6 | // int left = maxDepth(root->left); 7 | // int right = maxDepth(root->right); 8 | 9 | // return max(left, right) + 1; // add curr level also 10 | // Exact thing but in 1 line 11 | return root == NULL ? 0 : max(maxDepth(root -> left), maxDepth(root -> right)) + 1; 12 | } 13 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 18 (Binary Tree)/LCA in Binary Tree.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution { 4 | public: 5 | TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { 6 | if(!root || root == p || root == q) return root; 7 | 8 | TreeNode* left = lowestCommonAncestor(root->left, p, q); 9 | TreeNode* right = lowestCommonAncestor(root->right, p, q); 10 | 11 | if(left && right) return root; // if both l and r exist for a node, that node is the LCA. If one of them is null, just pass the non null val up so that the LCA can be found in the future above. 12 | if(left) return left; 13 | else return right; 14 | } 15 | }; 16 | 17 | 18 | //Sid 19 | bool nodeToRoot(TreeNode* root, vector &path, TreeNode *x) 20 | { 21 | if(root == NULL) 22 | return false; 23 | if(root == x) 24 | { 25 | path.push_back(root); 26 | return true; 27 | } 28 | bool l = nodeToRoot(root->left, path, x); 29 | if(l) 30 | { 31 | path.push_back(root); 32 | return true; 33 | } 34 | bool r = nodeToRoot(root->right, path, x); 35 | if(r) 36 | { 37 | path.push_back(root); 38 | return true; 39 | } 40 | return false; 41 | } 42 | TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { 43 | vector path1, path2; 44 | bool e1 = nodeToRoot(root, path1, p); 45 | bool e2 = nodeToRoot(root, path2, q); 46 | int i = 0, j = 0; 47 | reverse(path1.begin(), path1.end()); 48 | reverse(path2.begin(), path2.end()); 49 | while(i < path1.size() && j < path2.size()) 50 | { 51 | if(path1[i] == path2[j]) 52 | { 53 | i++; 54 | j++; 55 | } 56 | else 57 | break; 58 | } 59 | return path1[i-1]; 60 | } 61 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 18 (Binary Tree)/Level Order Traversal.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | vector> levelOrder(TreeNode* root) { 4 | vector> res; 5 | if(root == nullptr) return res; 6 | 7 | queue q; 8 | q.push(root); 9 | while(!q.empty()){ 10 | int N = q.size(); 11 | vector currlvl; 12 | for(int i = 0; ival); 16 | if(curr->left) q.push(curr->left); 17 | if(curr->right) q.push(curr->right); 18 | } 19 | res.push_back(currlvl); 20 | } 21 | return res; 22 | } 23 | 24 | //Sid 25 | int height(TreeNode *root) 26 | { 27 | if(root == NULL) 28 | return 0; 29 | int lh = height(root->left); 30 | int rh = height(root->right); 31 | return max(lh,rh)+1; 32 | } 33 | void helper(TreeNode *root, int level, vector &res) 34 | { 35 | if(root == NULL) 36 | return; 37 | if(level == 0) 38 | { 39 | res.push_back(root->val); 40 | return; 41 | } 42 | helper(root->left, level-1, res); 43 | helper(root->right, level-1, res); 44 | } 45 | vector> levelOrder(TreeNode* root) { 46 | vector> x; 47 | int h = height(root); 48 | for(int i = 0; i < h; i++) 49 | { 50 | vector temp; 51 | helper(root, i, temp); 52 | x.push_back(temp); 53 | } 54 | return x; 55 | } 56 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 18 (Binary Tree)/Level order in Spiral.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | vector> zigzagLevelOrder(TreeNode* root) { 4 | vector> res; 5 | if(root == nullptr) return res; 6 | 7 | bool reverse = false; // reverse the vector if true 8 | 9 | queue q; 10 | q.push(root); 11 | while(!q.empty()){ 12 | int N = q.size(); 13 | vector currlvl(N, 0); 14 | for(int i = 0; ival; 19 | else { 20 | currlvl[N-i-1] = curr->val; // adding from behind 21 | } 22 | if(curr->left) q.push(curr->left); 23 | if(curr->right) q.push(curr->right); 24 | } 25 | res.push_back(currlvl); 26 | reverse = !reverse; // for next level, negate it 27 | } 28 | return res; 29 | } 30 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 19 (Binary Tree)/Construct BTree from Inorder and Postorder.cpp: -------------------------------------------------------------------------------- 1 | // Slight modification of Inorder and Preorder. Traverse from back instead of front as it is postorder 2 | 3 | // Hari 4 | 5 | class Solution { 6 | public: 7 | int idx = 0; 8 | unordered_map m; 9 | 10 | TreeNode* helper(vectorinorder, vectorpostorder, int start, int end, int &idx){ 11 | if(start > end || idx < 0) return nullptr; 12 | TreeNode* curr = new TreeNode(postorder[idx--]); 13 | // for leaf node 14 | if(start == end) return curr; 15 | // search this element in inorder 16 | int mid = m[curr->val]; //gives the index of curr 17 | //recursive calls 18 | curr->right = helper(inorder, postorder, mid+1, end, idx); 19 | curr->left = helper(inorder, postorder, start, mid-1, idx); 20 | return curr; 21 | } 22 | 23 | TreeNode* buildTree(vector& inorder, vector& postorder) { 24 | // postorder gives us the parent each time when coming from back. 25 | //Search this parent in inorder using map O(1) 26 | // and left of this in left subtree, right in right subtree 27 | int N = inorder.size(); 28 | idx = N-1; 29 | m.clear(); 30 | // filling map using inorder elements 31 | for(int i = 0; i postorder, vector inorder, int &postInd, int l, int r) 42 | { 43 | if(postInd < 0 || r < l) 44 | return NULL; 45 | TreeNode *root = new TreeNode(postorder[postInd]); 46 | postInd--; 47 | if(l == r) 48 | return root; 49 | int i; 50 | for(i = 0; i < inorder.size(); i++) 51 | { 52 | if(inorder[i] == root->val) 53 | break; 54 | } 55 | root->right = build(postorder, inorder, postInd, i+1, r); 56 | root->left = build(postorder, inorder, postInd, l, i-1); 57 | 58 | 59 | 60 | return root; 61 | } 62 | TreeNode* buildTree(vector& inorder, vector& postorder) { 63 | //OM GAN GANAPATHAYE NAMO NAMAH 64 | //JAI SHRI RAM 65 | //JAI BAJRANGBALI 66 | //AMME NARAYANA. DEVI NARAYANA, LAKSHMI NARAYANA, BHADRE NARAYANA 67 | int postInd = postorder.size() - 1; 68 | int l = 0, r = inorder.size() - 1; 69 | return build(postorder, inorder, postInd, l, r); 70 | } 71 | }; 72 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 19 (Binary Tree)/Construct BTree from Inorder and Preorder(Hard).cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution { 4 | public: 5 | int idx = 0; 6 | unordered_map m; 7 | 8 | TreeNode* helper(vectorpreorder, vectorinorder, int start, int end){ 9 | // traverse preorder 10 | if(start > end) return nullptr; // base case 11 | TreeNode* curr = new TreeNode(preorder[idx++]); 12 | if(start == end) return curr; // when leaf node added 13 | int mid = m[curr->val]; // get parent index. 14 | curr->left = helper(preorder, inorder, start, mid-1); 15 | curr->right = helper(preorder, inorder, mid+1, end); 16 | return curr; 17 | } 18 | 19 | TreeNode* buildTree(vector& preorder, vector& inorder) { 20 | // preorder gives us the parent each time. Search this parent in inorder 21 | // (using map O(1)) and left of this in left subtree, right in right subtree 22 | idx = 0; 23 | m.clear(); 24 | int N = inorder.size(); 25 | // filling map using inorder elements 26 | for(int i = 0; ileft == nullptr && A->right == nullptr) return; 9 | if(A->left){ 10 | helper(A->left); // we will go till 3, and as next left is null, we will go up to 2 and then go to 4. 11 | TreeNode* temp = A->right; 12 | A->right = A->left; 13 | A->left = nullptr; 14 | 15 | TreeNode* curr = A->right; 16 | while(curr->right) curr = curr->right; 17 | //merge the old right 18 | curr->right = temp; 19 | } 20 | helper(A->right); 21 | } 22 | void flatten(TreeNode* root) { 23 | helper(root); 24 | } 25 | }; 26 | 27 | //Sid 28 | void flatten(TreeNode* root) { 29 | if(root == NULL || (root->left == NULL && root->right == NULL)) 30 | return; 31 | if(root->left != NULL) 32 | { 33 | flatten(root->left); 34 | TreeNode *temp = root->right; 35 | root->right = root->left; 36 | root->left = NULL; 37 | TreeNode *cur = root->right; 38 | while(cur->right != NULL) 39 | { 40 | cur = cur->right; 41 | } 42 | cur->right = temp; 43 | 44 | } 45 | flatten(root->right); 46 | } 47 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 19 (Binary Tree)/Maximum Path Sum(Hard).cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution { 4 | // Best explanation: https://www.youtube.com/watch?v=6cA_NDtpyz8&ab_channel=MichaelMuinosMichaelMuinos 5 | public: 6 | int maxP = INT_MIN; 7 | 8 | int helper(TreeNode* curr){ 9 | // do postorder traversal standard 10 | if(curr == nullptr) return 0; 11 | 12 | //If result is -ve val, we won't send this val to curr. Send 0 instead 13 | int left = max(0,helper(curr->left)); 14 | int right = max(0,helper(curr->right)); 15 | // when coming out of recursive calls we find new maxP 16 | 17 | maxP = max(maxP, left + right + curr->val); 18 | // maxP gets compared, updated with maxP value of curr's subtrees 19 | 20 | return max(left, right) + curr->val; 21 | // Return value will be used to check maxP considering tree's main root in path. 22 | 23 | } 24 | 25 | int maxPathSum(TreeNode* root) { 26 | helper(root); 27 | return maxP; 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 19 (Binary Tree)/Symmetric Tree(Mirror of itself).cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution { 4 | public: 5 | bool helper(TreeNode* r1, TreeNode* r2){ 6 | if(!r1 && !r2) return true; 7 | if(!r1 || !r2) return false; 8 | 9 | if(r1 && r2 && r1->val == r2->val){ 10 | // check their subtrees 11 | return helper(r1->left, r2->right) && helper(r1->right, r2->left); 12 | } 13 | return false; 14 | } 15 | 16 | 17 | bool isSymmetric(TreeNode* root) { 18 | return helper(root, root); 19 | } 20 | }; 21 | 22 | //Sid 23 | bool helper(TreeNode *root1, TreeNode *root2) 24 | { 25 | if(root1 == NULL && root2 == NULL) 26 | return true; 27 | else if(root1 == NULL || root2 == NULL) 28 | return false; 29 | bool x = helper(root1->left, root2->right); 30 | bool y = helper(root1->right, root2->left); 31 | if(root1->val == root2->val && x && y) 32 | return true; 33 | return false; 34 | } 35 | bool isSymmetric(TreeNode* root) { 36 | //OM GAN GANAPATHAYE NAMO NAMAH 37 | //JAI SHRI RAM 38 | //JAI BAJRANGBALI 39 | //AMME NARAYANA, DEVI NARAYANA, LAKSHMI NARAYANA, BHADRE NARAYANA 40 | return helper(root->left, root->right); 41 | } 42 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 2 (Arrays)/Best Time to Buy and Sell Stock - 1.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int maxProfit(vector& prices) { 4 | int max_profit = 0, min_price = INT_MAX; 5 | int N = prices.size(); 6 | 7 | for(int i = 0; i right[j]) 26 | { 27 | a[k] = right[j]; 28 | count = count + (n1-i); 29 | j++; 30 | k++; 31 | } 32 | else 33 | { 34 | a[k] = left[i]; 35 | i++; 36 | k++; 37 | } 38 | } 39 | while(i < n1 ) 40 | { 41 | a[k] = left[i]; 42 | i++; 43 | k++; 44 | } 45 | while(j < n2) 46 | { 47 | a[k] = right[j]; 48 | j++; 49 | k++; 50 | } 51 | return count; 52 | 53 | } 54 | long long int inversions(long long int a[], long long int l, long long int r) 55 | { 56 | long long int count = 0; 57 | if(r > l) 58 | { 59 | long long int mid = l + (r-l)/2; 60 | count += inversions(a, l, mid); 61 | count += inversions(a, mid+1, r); 62 | count += merge(a, l, mid, r); 63 | } 64 | return count; 65 | } 66 | long long int inversionCount(long long arr[], long long N) 67 | { 68 | // Your Code Here 69 | return inversions(arr, 0, N-1); 70 | } 71 | 72 | }; 73 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 2 (Arrays)/Next Permutation.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void nextPermutation(vector& nums) { 4 | int N = nums.size(), ind = -1; 5 | for(int i = N-1; i>0; i--){ 6 | if(nums[i-1] < nums[i]){ 7 | ind = i-1; 8 | break; 9 | } 10 | } 11 | 12 | if(ind == -1) reverse(nums.begin(), nums.end()); 13 | else { 14 | // check smallest no > nums[ind] 15 | int minIdx; 16 | for(int i = N-1; i>ind; i--){ 17 | if(nums[i] > nums[ind]){ 18 | minIdx = i; 19 | break; 20 | } 21 | } 22 | 23 | swap(nums[minIdx], nums[ind]); 24 | 25 | reverse(nums.begin() + ind + 1, nums.end()); 26 | } 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 2 (Arrays)/Pascal Triangle. cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector> generate(int numRows) { 4 | vector> res; 5 | for(int line = 1; line <= numRows; line++){ 6 | int C = 1; // all lines start w 1 7 | vector temp; 8 | for(int i = 1; i <= line; i++){ 9 | temp.push_back(C); 10 | C = C * (line - i)/i; 11 | } 12 | res.push_back(temp); 13 | temp.clear(); 14 | } 15 | return res; 16 | } 17 | }; 18 | 19 | // Another method 20 | 21 | class Solution { 22 | public: 23 | vector> generate(int numRows) { 24 | vector> pascal; 25 | vector temp; 26 | temp.push_back(1); 27 | pascal.push_back(temp); 28 | for(int i = 1; i < numRows; i++) 29 | { 30 | temp.clear(); 31 | int size = i + 1; 32 | for(int j = 0; j < size; j++) 33 | { 34 | if(j == 0 || j == size - 1) 35 | temp.push_back(1); 36 | else 37 | { 38 | int x = pascal[i-1][j] + pascal[i-1][j-1]; 39 | temp.push_back(x); 40 | } 41 | } 42 | pascal.push_back(temp); 43 | } 44 | return pascal; 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 2 (Arrays)/Rotate Matrix.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | void rotate(vector>& matrix) { 4 | // to turn clockwise -> do transpose and then reverse each row 5 | int N = matrix.size(); 6 | 7 | for(int i = 0; i>& matrix) { 2 | bool rowFlag = false; 3 | bool colFlag = false; 4 | //scan the first row 5 | for(int i = 0; i < matrix[0].size(); i++) 6 | { 7 | if(matrix[0][i] == 0) 8 | rowFlag = true; 9 | } 10 | //scan the first column 11 | for(int i = 0; i < matrix.size(); i++) 12 | { 13 | if(matrix[i][0] == 0) 14 | colFlag = true; 15 | } 16 | for(int i = 1; i < matrix.size(); i++) 17 | { 18 | for(int j = 1; j < matrix[i].size(); j++) 19 | { 20 | if(matrix[i][j] == 0) 21 | { 22 | matrix[i][0] = 0; 23 | matrix[0][j] = 0; 24 | } 25 | } 26 | } 27 | for(int i = 1; i < matrix.size(); i++) 28 | { 29 | for(int j = 1; j < matrix[i].size(); j++) 30 | { 31 | if(matrix[i][0] == 0 || matrix[0][j] == 0) 32 | { 33 | matrix[i][j] = 0; 34 | } 35 | } 36 | } 37 | if(rowFlag ==true) 38 | { 39 | for(int i = 0; i < matrix[0].size(); i++) 40 | { 41 | matrix[0][i] = 0; 42 | } 43 | } 44 | if(colFlag == true) 45 | { 46 | for(int i = 0; i < matrix.size(); i++) 47 | matrix[i][0] = 0; 48 | } 49 | } 50 | 51 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 20 (BST)/Check if BT is BST.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution { 4 | public: 5 | bool helper(TreeNode* root, TreeNode* minNode, TreeNode* maxNode){ 6 | if(root == nullptr) return true; //leaf reached 7 | else if(maxNode && root->val >= maxNode->val || minNode && root->val <= minNode->val) { 8 | return false; 9 | } 10 | return helper(root->left, minNode, root) && helper(root->right, root, maxNode); 11 | } 12 | 13 | bool isValidBST(TreeNode* root) { 14 | return helper(root, NULL, NULL); 15 | } 16 | }; 17 | 18 | 19 | //Sid 20 | 21 | class Solution { 22 | public: 23 | bool helper(TreeNode *root, long long int min, long long int max) 24 | { 25 | if(root == NULL) 26 | return true; 27 | if(root->val < max && root->val > min) 28 | { 29 | if(helper(root->left, min, root->val) && helper(root->right, root->val, max)) 30 | return true; 31 | else 32 | return false; 33 | } 34 | else 35 | return false; 36 | } 37 | bool isValidBST(TreeNode* root) { 38 | return helper(root, LONG_MIN, LONG_MAX); 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 20 (BST)/Construct BST from given keys.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution { 4 | public: 5 | TreeNode* bstFromPreorder(vector& preorder) { 6 | // we use stack to keep conteact of last node added. This way, no need to 7 | //start from root again and again to comapre each element 8 | TreeNode* root = new TreeNode(preorder[0]); 9 | stack s; 10 | s.push(root); 11 | 12 | for(int i = 1; ival > preorder[i]){ 15 | // add this preorder element to left of root (curr) 16 | TreeNode* newNode = new TreeNode(preorder[i]); 17 | curr->left = newNode; 18 | s.push(newNode); 19 | } else { 20 | // if predorder element is > than curr root, it may be greater than root of curr root also. Check it, and when this condt fails add it there 21 | while(!s.empty() && s.top()->val < preorder[i]){ 22 | curr = s.top(); s.pop(); 23 | } 24 | // when preorder ele less than a stack ele and comes out of while, 25 | // the curr will show last node which can host preorder ele in right 26 | 27 | TreeNode* newNode = new TreeNode(preorder[i]); 28 | curr->right = newNode; 29 | s.push(newNode); 30 | } 31 | } 32 | return root; 33 | } 34 | }; 35 | 36 | //Sid 37 | class Solution { 38 | public: 39 | TreeNode *helper(ListNode *start, ListNode *end) 40 | { 41 | if(start == end) 42 | { 43 | return NULL; 44 | } 45 | if(start->next == end) 46 | { 47 | TreeNode *root = new TreeNode(start->val); 48 | return root; 49 | } 50 | ListNode *slow = start, *fast = start; 51 | while(fast != end && fast->next != end) 52 | { 53 | slow = slow->next; 54 | fast = fast->next->next; 55 | } 56 | TreeNode *root = new TreeNode(slow->val); 57 | root->left = helper(start, slow); 58 | root->right = helper(slow->next, end); 59 | return root; 60 | } 61 | TreeNode* sortedListToBST(ListNode* head) { 62 | ListNode *start = head, *end = NULL; 63 | return helper(start, end); 64 | } 65 | }; 66 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 20 (BST)/Inorder predecessor and succ in BST.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | // This function finds predecessor and successor of key in BST. 4 | // It sets pre and suc as predecessor and successor respectively 5 | void findPreSuc(Node* root, Node*& pre, Node*& suc, int key) 6 | { 7 | // base condition 8 | if (!root) return ; 9 | 10 | // target node found 11 | if (root->key == key) 12 | { 13 | if (root->left) 14 | { 15 | Node* curr = root->left; // inorder predecessor 16 | while (curr->right) // rightmost node in left subT 17 | curr = curr->right; 18 | pre = curr ; 19 | } 20 | 21 | if (root->right) 22 | { 23 | Node* curr = root->right ; // inorder successor 24 | while (curr->left) // leftmost node in right subT 25 | curr = curr->left ; 26 | suc = curr ; 27 | } 28 | return ; 29 | } 30 | 31 | if (root->key > key) 32 | { 33 | suc = root ; 34 | findPreSuc(root->left, pre, suc, key) ; 35 | } 36 | else 37 | { 38 | pre = root ; 39 | findPreSuc(root->right, pre, suc, key) ; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 20 (BST)/LCA of BST.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution { 4 | public: 5 | TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { 6 | // This is for normal BT. BST property not used 7 | // if(!root) return nullptr; 8 | // if(root == p || root == q) return root; 9 | 10 | // TreeNode* left = lowestCommonAncestor(root->left, p,q); 11 | // TreeNode* right = lowestCommonAncestor(root->right, p,q); 12 | 13 | // if(left && right) return root; 14 | // if(left) return left; 15 | // else return right; 16 | 17 | // BST usage 18 | // we keep recursing till p and q split up. That place is the LCA of BST 19 | if(root->val < p->val && root->val < q->val) return lowestCommonAncestor(root->right,p,q); 20 | if(root->val > p->val && root->val > q->val) return lowestCommonAncestor(root->left,p,q); 21 | return root; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 20 (BST)/Populate next right pointers.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution { 4 | public: 5 | // trace it, you will get it 6 | void assignLowerLvl(Node* start){ 7 | Node* curr = start; 8 | while(curr){ 9 | curr->left->next = curr->right; 10 | if(curr->next){ 11 | curr->right->next = curr->next->left; 12 | } 13 | curr = curr->next; 14 | } 15 | } 16 | Node* connect(Node* root) { 17 | // initially all next are NULL. 18 | Node* leftNode = root; 19 | while(leftNode && leftNode->left){ 20 | assignLowerLvl(leftNode); 21 | leftNode = leftNode->left; 22 | } 23 | return root; 24 | } 25 | }; 26 | 27 | //Sid 28 | class Solution { 29 | public: 30 | Node* connect(Node* root) { 31 | if(root == NULL || root->left == NULL || root->right == NULL) 32 | return root; 33 | //connection part 34 | root->left->next = root->right; 35 | if(root->next != NULL) 36 | { 37 | root->right->next = root->next->left; 38 | } 39 | connect(root->left); 40 | connect(root->right); 41 | return root; 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 20 (BST)/Search in BST.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution { 4 | public: 5 | TreeNode* searchBST(TreeNode* root, int val) { 6 | TreeNode* curr = root; 7 | while(curr){ 8 | if(curr->val == val) return curr; //base 9 | else if(curr->val < val){ 10 | curr = curr->right; 11 | } 12 | else curr = curr->left; 13 | } 14 | return nullptr; 15 | } 16 | }; 17 | 18 | //Sid 19 | class Solution { 20 | public: 21 | TreeNode* searchBST(TreeNode* root, int val) { 22 | if(root == NULL) 23 | return root; 24 | if(root->val == val) 25 | return root; 26 | else if(root->val > val) 27 | { 28 | return searchBST(root->left, val); 29 | } 30 | else 31 | { 32 | return searchBST(root->right, val); 33 | } 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 21 (BST)/BST Iterator.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class BSTIterator { 4 | public: 5 | // while a list can be used to iterate tree, store value and check 6 | // space will be O(N). We will do partial inorder w stack for O(h) 7 | stack s; 8 | BSTIterator(TreeNode* root) { 9 | helper(root); 10 | } 11 | 12 | void helper(TreeNode* curr){ 13 | // move left as per inorder, keep adding to stack in the process 14 | while(curr) { 15 | s.push(curr); 16 | curr = curr->left; 17 | } 18 | } 19 | 20 | int next() { // explores right subT (if exists) of stack top node (inorder fashion) 21 | TreeNode* temp = s.top(); s.pop(); 22 | helper(temp->right); 23 | return temp->val; 24 | } 25 | 26 | bool hasNext() { 27 | return !s.empty(); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 21 (BST)/Find pair with sum in BST.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution { 4 | public: 5 | bool helper(TreeNode* root, unordered_set &s, int k){ 6 | if(!root) return false; 7 | if(s.find(k-root->val) != s.end()) return true; 8 | s.insert(root->val); 9 | return helper(root->left, s, k) || helper(root->right, s, k); 10 | } 11 | bool findTarget(TreeNode* root, int k) { 12 | unordered_set s; 13 | return helper(root, s, k); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 21 (BST)/Floor and ceil of BST.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | void helper(Node* root, int key, int& floor, int& ceil) 4 | { 5 | 6 | while (root) { 7 | // when the key itself is found, it is both the floor and ceil. 8 | if (root->data == key) { 9 | ceil = root->data; 10 | floor = root->data; 11 | return; 12 | } 13 | // if root < key, root is the floor (first smallest val) and ceil is somewhere in right subT 14 | if (key > root->data) { 15 | floor = root->data; 16 | root = root->right; 17 | } 18 | else { // converse 19 | ceil = root->data; 20 | root = root->left; 21 | } 22 | } 23 | return; 24 | } 25 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 21 (BST)/K-th largest element in BST.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | // return the Kth largest element in the given BST rooted at 'root' 4 | class Solution 5 | { 6 | public: 7 | int kLarge = 0, c = 0; 8 | void helper(Node *root, int K){ 9 | if(!root || c >= K) return; 10 | // go right then left (reverse inorder) 11 | helper(root->right, K); 12 | c++; 13 | if(c == K){ 14 | kLarge = root->data; 15 | return; 16 | } 17 | // now go left 18 | return helper(root->left, K); 19 | } 20 | int kthLargest(Node *root, int K) 21 | { 22 | helper(root, K); 23 | return kLarge; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 21 (BST)/K-th smallest in BST.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution { 4 | public: 5 | int index = 1, kthSmall = 0; 6 | void inOrder(TreeNode* root, int k){ 7 | if(!root) return; 8 | inOrder(root->left, k); 9 | // reach smallest ele on left most of tree 10 | if(index++ == k) { 11 | kthSmall = root->val; return; 12 | } 13 | inOrder(root->right, k); 14 | } 15 | 16 | int kthSmallest(TreeNode* root, int k) { 17 | inOrder(root, k); 18 | return kthSmall; 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 21 (BST)/Max sum BST in BT(Hard).cpp: -------------------------------------------------------------------------------- 1 | // Same logic as "Size of largest BST in BT". Instead of keeping track of sum in BSTNode, I keep track of no. of elements 2 | 3 | // Hari 4 | 5 | class Solution { 6 | public: 7 | // define a struct with parameters that keep check of whether BST exists 8 | // watch Tushar roy video on YT for explanation 9 | struct BSTNode { 10 | bool isBST; 11 | int min; 12 | int max; 13 | int sum; 14 | }; 15 | BSTNode helper(TreeNode* curr, int &ans){ 16 | if(curr){ 17 | BSTNode left = helper(curr->left, ans); 18 | BSTNode right = helper(curr->right, ans); 19 | // for a node's isBST to be true, its left and right subT should 20 | // also be BSTs, and node's val > left's max and val > left.max && curr->val < right.min; 22 | // sum param of this particular node 23 | int sum = left.sum + right.sum + curr->val; 24 | // only if a BST can be formed at this curr will we modify ans 25 | if(isBST) ans = max(ans, sum); 26 | // return status to higher levels 27 | return {isBST, min(curr->val, left.min), max(curr->val, right.max), sum }; 28 | } else return {true, INT_MAX, INT_MIN, 0}; 29 | } 30 | 31 | int maxSumBST(TreeNode* root) { 32 | int ans = 0; 33 | helper(root, ans); 34 | return ans; 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 21 (BST)/Serialize and Deserialize(Hard).cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Codec { 4 | public: 5 | // Watch Back to Back SWE's vid for explanation 6 | // Encodes a tree to a single string. 7 | string serialize(TreeNode* root) { 8 | if(!root) return "#"; // null nodes get converted to # in string 9 | return to_string(root->val) + "," + serialize(root->left) + "," + serialize(root->right); // preorder conversion to string separated by commas 10 | } 11 | 12 | // Decodes your encoded data to tree. 13 | TreeNode* deserialize(string data) { 14 | // take the string created in serialize and convert it back to BTree nodes 15 | if(data == "#") return nullptr; 16 | stringstream ss(data); // makes string operations easier. data is assigned to ss which is passed to helper function 17 | return desHelper(ss); 18 | } 19 | 20 | TreeNode* desHelper(stringstream &ss){ 21 | string word; 22 | getline(ss,word,','); // each time we get a new element from stringstream to convert to node and add to BT. Delimiter is comma. 23 | if(word == "#") return nullptr; 24 | else { 25 | TreeNode* curr = new TreeNode(stoi(word)); 26 | curr->left = desHelper(ss); 27 | curr->right = desHelper(ss); 28 | return curr; 29 | } 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 23 (Graphs)/BFS.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | // When there are no unconnected components in graph, no need to have an upper for loop for checking each vertex 4 | 5 | class Solution 6 | { 7 | public: 8 | //Function to return Breadth First Traversal of given graph. 9 | vectorbfsOfGraph(int V, vector adj[]){ 10 | vector bfs; 11 | vector vis(V, 0); 12 | queue q; 13 | q.push(0); 14 | vis[0] = 1; 15 | while(!q.empty()) { 16 | int node = q.front(); 17 | q.pop(); 18 | bfs.push_back(node); 19 | 20 | for(auto it : adj[node]) { 21 | if(!vis[it]) { 22 | q.push(it); 23 | vis[it] = 1; 24 | } 25 | } 26 | } 27 | 28 | return bfs; 29 | } 30 | }; 31 | 32 | // When there are some unconnected components in graph 33 | 34 | class Solution 35 | { 36 | public: 37 | //Function to return Breadth First Traversal of given graph. 38 | vectorbfsOfGraph(int V, vector adj[]){ 39 | vector bfs; 40 | vector vis(V+1, 0); 41 | 42 | for(int i = 0; i q; 45 | q.push(i); 46 | vis[i] = 1; 47 | 48 | while(!q.empty()) { 49 | int node = q.front(); 50 | q.pop(); 51 | bfs.push_back(node); 52 | 53 | for(auto it : adj[node]) { 54 | if(!vis[it]) { 55 | q.push(it); 56 | vis[it] = 1; 57 | } 58 | } 59 | } 60 | } 61 | } 62 | 63 | return bfs; 64 | } 65 | }; 66 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 23 (Graphs)/Bipartite Check(BFS).cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution 4 | { 5 | public: 6 | bool cycleChk(int node, int parent, vectoradj[], vector &vis){ 7 | // We use DFS this time. If a node is found to be already visited 8 | // and it is NOT the parent of our current node, then it has already been 9 | // traversed and hence is a cycle 10 | vis[node] = 1; 11 | for(auto it: adj[node]){ 12 | if(!vis[it]){ 13 | if(cycleChk(it, node, adj, vis)) return true; 14 | // as DFS keeps going down, if any iteration gives a True, return 15 | // true. No need to keep going down in DFS further 16 | } else { 17 | if(it != parent) return true; 18 | } 19 | } 20 | return false; 21 | } 22 | //Function to detect cycle in an undirected graph. 23 | bool isCycle(int V, vectoradj[]) 24 | { 25 | vector vis(V+1,0); 26 | for(int i = 0; i adj[], int color[]){ 7 | if(color[node] == -1) color[node] = 1; 8 | // Same logic as BFS. There we used Queue, here we just keep recursing 9 | // and exploring each node and constantly checking the color 10 | for(auto it: adj[node]){ 11 | if(color[it] == -1){ 12 | color[it] = 1 - color[node]; 13 | if(!helper(it, adj, color)) return false; 14 | } else { 15 | if(color[it] == color[node]) return false; 16 | } 17 | } 18 | return true; 19 | } 20 | 21 | 22 | bool isBipartite(int V, vectoradj[]){ 23 | int color[V]; // maintains color of nodes (0 or 1 are the available colors) 24 | memset(color, -1, sizeof(color)); // initial assignment 25 | for(int i = 0; i copies; 7 | Node* cloneGraph(Node* node) { 8 | // very simple implementation of a complex question 9 | 10 | // node points to the current node traversed in original graph 11 | if(!node) return nullptr; // base 12 | 13 | if(copies.find(node) == copies.end()) { 14 | // node not found in copied graph. Add it 15 | copies[node] = new Node(node->val, {}); 16 | 17 | for(Node* it: node->neighbors){ 18 | copies[node]->neighbors.push_back(cloneGraph(it)); 19 | } 20 | } 21 | return copies[node]; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 23 (Graphs)/Cycle Detection Directed Graph (BFS)(Kahn).cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | // We can use Kahn's algo (used in Topological Sort BFS) here. That algo works only 4 | // in DAG (directed acyclic (no cycle) graph). And topo sort is just linear ordering of 5 | // vertices. If vertex count doesn't match, then cycle exists in graph 6 | 7 | class Solution 8 | { 9 | public: 10 | //Function to detect cycle in a directed graph. 11 | bool isCyclic(int V, vector adj[]) 12 | { 13 | queue q; 14 | vector indegree(V,0); 15 | 16 | // assign indegrees 17 | for(int i = 0; i res; 28 | while(!q.empty()){ 29 | int curr = q.front(); q.pop(); 30 | count++; 31 | res.push_back(curr); 32 | for(auto it: adj[curr]) { 33 | indegree[it]--; 34 | if(indegree[it] == 0) q.push(it); 35 | } 36 | } 37 | 38 | if(count == V) return false; // no cycle 39 | return true; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 23 (Graphs)/Cycle Detection Directed Graph(DFS).cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution 4 | { 5 | public: 6 | bool chkCycle(int node, vector adj[], int vis[], int dfsVis[]){ 7 | vis[node] = 1; dfsVis[node] = 1; 8 | for(auto it: adj[node]) { 9 | // dfs 10 | if(!vis[it]){ 11 | // not visited. Go to its child and then its child and so on. 12 | // If any 1 of the node is found to have cycle, then return 13 | // true through all recursions and then pass that true to isCyclic 14 | if(chkCycle(it, adj, vis, dfsVis)) return true; 15 | } else { 16 | // node is visited. If it is not visited in dfsVis then no probs, 17 | // as the node has been visited before but not on this traversal. 18 | if(dfsVis[it] == 1) return true; 19 | } 20 | } 21 | // after this node traversal is over and there are no more adj nodes for it, make its dfsVis 0. vis will NOT change 22 | dfsVis[node] = 0; 23 | return false; // pass this value higher recursive levels 24 | } 25 | //Function to detect cycle in a directed graph. 26 | bool isCyclic(int V, vector adj[]) 27 | { 28 | // we have 2 arrays instead of 1 to keep track of visited. 29 | // vis is for all the nodes overall, and dfsVis is for 30 | // maintaining visited nodes in this current iteration only. 31 | int vis[V], dfsVis[V]; 32 | memset(vis, 0, sizeof vis); 33 | memset(dfsVis, 0, sizeof dfsVis); 34 | 35 | for(int i = 0; iadj[], vector &vis){ 7 | // We use BFS this time. If a node is found to be already visited 8 | // and it is NOT the parent of our current node, then it has already been 9 | // traversed and hence is a cycle 10 | queue> q; 11 | vis[node] = 1; 12 | q.push({node, -1}); // initial node won't have parent 13 | 14 | while(!q.empty()){ 15 | int node = q.front(). first; 16 | int parent = q.front().second; 17 | q.pop(); 18 | 19 | for(auto it: adj[node]){ 20 | if(!vis[it]){ 21 | vis[it] = 1; 22 | q.push({it, node}); 23 | } else { 24 | // "it" node has been traversed already 25 | if(parent != it) return true; 26 | } 27 | } 28 | } 29 | return false; 30 | } 31 | //Function to detect cycle in an undirected graph. 32 | bool isCycle(int V, vectoradj[]) 33 | { 34 | vector vis(V,0); 35 | for(int i = 0; iadj[], vector &vis){ 7 | // We use DFS this time. If a node is found to be already visited 8 | // and it is NOT the parent of our current node, then it has already been 9 | // traversed and hence is a cycle 10 | vis[node] = 1; 11 | for(auto it: adj[node]){ 12 | if(!vis[it]){ 13 | if(cycleChk(it, node, adj, vis)) return true; 14 | // as DFS keeps going down, if any iteration gives a True, return 15 | // true. No need to keep going down in DFS further 16 | } else { 17 | if(it != parent) return true; 18 | } 19 | } 20 | return false; 21 | } 22 | //Function to detect cycle in an undirected graph. 23 | bool isCycle(int V, vectoradj[]) 24 | { 25 | vector vis(V+1,0); 26 | for(int i = 0; i &res, vector &vis, vector adj[]) { 8 | // add this unvisited node to res 9 | res.push_back(node); 10 | vis[node] = 1; 11 | // recursively call its neighbor, which will call its neighbor and so on 12 | // once calls are over, they trace back and see if any other unvisited 13 | // neighbor is there for an already visited node 14 | for(auto it: adj[node]){ 15 | if(!vis[it]) helper(it, res, vis, adj); 16 | } 17 | } 18 | //Function to return a list containing the DFS traversal of the graph. 19 | vectordfsOfGraph(int V, vector adj[]) 20 | { 21 | vector res; 22 | vector vis(V,0); 23 | for(int i = 0; iv edge exists in graph, in topo sort order u comes before v. Kahn's algo always starts from a vertex w indegree 0. As nodes are added to final ans, 7 | // their adj node's dependency factor dec. by 1 and hence we subtract. 8 | 9 | class Solution 10 | { 11 | public: 12 | //Function to return list containing vertices in Topological order. 13 | vector topoSort(int V, vector adj[]) 14 | { 15 | queue q; 16 | vector indegree(V,0); 17 | // add indegree values for all node 18 | for(int i = 0; iit is edge so it's indegree += 1 20 | } 21 | 22 | // whichever nodes have 0 indegree, add them to Q 23 | for(int i = 0; i res; 29 | while(!q.empty()){ 30 | int curr = q.front(); q.pop(); 31 | res.push_back(curr); 32 | 33 | for(auto it: adj[curr]){ 34 | indegree[it]--; 35 | if(indegree[it] == 0) q.push(it); 36 | } 37 | } 38 | 39 | return res; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 23 (Graphs)/Topological Sort(DFS).cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution 4 | { 5 | public: 6 | void helper(int node, vector &vis, stack &s, vector adj[]){ 7 | vis[node] = 1; 8 | 9 | for(auto it: adj[node]){ 10 | if(!vis[it]) 11 | helper(it, vis, s, adj); 12 | } 13 | s.push(node); 14 | } 15 | //Function to return list containing vertices in Topological order. 16 | vector topoSort(int V, vector adj[]) 17 | { 18 | stack s; 19 | // after traversing a node when there is not adj node left, add that node into 20 | // stack. So always child is added first and then parent. So whe popping out 21 | // from stack, parent comes before child in topologicl sort sequence 22 | vector vis(V,0); 23 | for(int i = 0; i res; 28 | while(!s.empty()){ 29 | res.push_back(s.top()); s.pop(); 30 | } 31 | return res; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 24 (Graphs)/Bellman Ford's Algo.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | int isNegativeWeightCycle(int n, vector>edges){ 4 | // edges[i][0,1,2] = u,v, weight respectively 5 | // get dist array 6 | int INF = 1e9+7; 7 | vector dist(n, INF); 8 | dist[0] = 0; //source 9 | 10 | for(int i = 1; i<=n-1; i++){ // relaxation for n-1 times 11 | for(auto it: edges){ 12 | if(dist[it[0]] + it[2] < dist[it[1]]){ 13 | dist[it[1]] = dist[it[0]] + it[2]; 14 | } 15 | } 16 | } 17 | 18 | // try relaxing once more. If any dist val changes then -ve cycle exists 19 | int res = 0; 20 | for(auto it: edges){ 21 | if(dist[it[0]] + it[2] < dist[it[1]]){ 22 | res = 1; 23 | return res; 24 | } 25 | } 26 | 27 | return res; 28 | }; 29 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 24 (Graphs)/Bridges in Graph (VHard).cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | #include 4 | using namespace std; 5 | 6 | // Bridges are edges that if you remove them, the graph breaks. We will do DFS here to find # of bridges 7 | // We use 2 arrays tin[] (time of insertion) and low[] (smallest time in adj nodes of curr) 8 | // Once dfs(it) trav is finished, we try to update its low[] and then check condition low[it] > tin[node] 9 | // If condt true, then that edge is a bridge. 10 | // low[node] is either time of insertion (assigned at start) or lowest time of insertion across adj nodes 11 | void dfs(int node, int parent, vector &vis, vector &tin, vector &low, int &timer, vector adj[]){ 12 | vis[node] = 1; 13 | tin[node] = low[node] = timer++; // first dfs traversal both arrays get same val 14 | 15 | for(auto it: adj[node]){ 16 | if(it == parent) continue; // dont want to go back in dfs. We want forward progress 17 | 18 | if(!vis[it]){ 19 | dfs(it, node, vis, tin, low, timer, adj); 20 | // after dfs calls over, we update low 21 | low[node] = min(low[node], low[it]); 22 | 23 | // bridges condition check - if low[it] is lesser, then the other way (not edge removed) can reach node easier. 24 | if(low[it] > tin[node]) cout << node << "--" << it << "is a bridge" << endl; 25 | } else { 26 | // already visited. Just update low. Bridge cant exist as its already visited without 27 | // going thru bridge 28 | low[node] = min(low[node], tin[it]); 29 | } 30 | 31 | } 32 | } 33 | 34 | 35 | 36 | int main() { 37 | int N, m; 38 | cin >> N >> m; 39 | vector adj[N]; 40 | // creating the graph from user input 41 | for(int i = 0; i> u >> v; 44 | adj[u].push_back(v); 45 | adj[v].push_back(u); 46 | } 47 | 48 | vector tin(N, -1); 49 | vector low(N, -1); 50 | vector vis(N, 0); // for dfs 51 | int timer = 0; 52 | 53 | for(int i = 0; i 4 | using namespace std; 5 | // Implementing dijkstra algo for single source shortest path using DFS and Priority Q (minHeap) 6 | // minHeap ensures only min distance node chosen as source. So even if same node has 2 dist vals in minH 7 | // the smaller wt one will be chosen. The other one will also be checked, but will 100% not give better result 8 | int main() { 9 | // adj list has neighbour node and weight as pairs. minHeap has dist and "from" node ias pair 10 | 11 | int n, m, source; // nodes and edges. We are creating the graph 12 | cin >> n >> m; 13 | vector> graph[n+1]; 14 | 15 | int u,v,wt; // from node, to node and wt btw them 16 | for(int i = 0; i> u >> v >> wt; 18 | graph[u].push_back({v,wt}); // graph[u].push_back(make_pair(v,wt)); 19 | graph[v].push_back({u,wt}); // both as undirected graph 20 | } 21 | 22 | cin >> source; 23 | 24 | // Dijkstra 25 | priority_queue, vector>, greater> pq; // {dist, from} 26 | vector dist(n+1, INT_MAX); // dist array for all nodes. Will hold all ans 27 | 28 | dist[source] = 0; 29 | pq.push(make_pair(0, source)); 30 | 31 | while(!pq.empty()){ 32 | int dist = pq.top().first; 33 | int prev = pq.top().second; pq.pop(); 34 | 35 | // traverse its adj nodes 36 | for(auto it: graph[prev]){ 37 | int next = it.first; // "it->first" iff we used iterator like vector>::iterator it 38 | int nextDist = it.second; 39 | if(dist + nextDist < dist[next]) { 40 | dist[next] = dist + nextDist; 41 | pq.push(make_pair(dist[next], next)); 42 | } 43 | 44 | } 45 | 46 | } 47 | 48 | // all min dist will be in dist vector 49 | for(int i = 1; i<=n; i++){ 50 | cout << dist[i] << " "; 51 | } 52 | 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 24 (Graphs)/Disjoint Set(Union by rank and Path Compression).cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | #include 4 | using namespace std; 5 | 6 | // Disjoint Sets help cluster nodes together. Used in Kruskal's Algo. 7 | 8 | int parent[10000]; 9 | int rank[10000]; 10 | 11 | void makeSet(int N) { 12 | // for all N nodes, it makes their parent as themselves (self loop) and init rank to be 0 13 | // rank is the ht of the tree formed from that node to the leaf. It inc in val by 1 iff 14 | // both nodes ranks are equal. Rank helps figure out which graph cluster is smaller, so that this 15 | // small tree is added to the bigger tree (higher rank) to ensure ht doesnt inc. If viceversa is done 16 | // then ht of final graph/tree increases 17 | 18 | for(int i = 0; i<=N; i++){ 19 | parent[i] = i; 20 | rank[i] = 0; 21 | } 22 | } 23 | 24 | void findParent(int node){ // TC -> O(4*alpha) which is const time for each node 25 | // Finds the parent node of a node. 26 | // 2->3->5 is tree. findParent(5) goes to 3 and then 2 and then 2 (self loop) 27 | if(node == parent[node]) return node; // once self loop happens that is the parent(2) of node(5) 28 | 29 | return parent[node] = findParent(parent[node]); // keep assigning parent as u go up the tree. So next time 30 | // findParent(5) is called, it will just return 2 instead of going from 5 -> 3 -> 2 -> 2. 31 | // This is called PATH COMPRESSION 32 | } 33 | 34 | void union(int u, int v){ 35 | // cluster u and v together and assign one of them as parent 36 | u = findParent(u); 37 | v = findParent(v); 38 | 39 | if(rank[u] < rank[v]) { 40 | // u is smaller. Attach u to v. Read comment in makeSet() 41 | parent[u] = v; 42 | } else if(rank[v] < rank[u]) { 43 | parent[v] = u; 44 | } else { 45 | // both rank equal. v can attach to u, and vice versa is also fine. But don't forget to inc rank 46 | // as depth of tree will inc in this case 47 | parent[v] = u; // Attach v to u. 48 | rank[u]++; // u's rank inc by 1 49 | } 50 | } 51 | 52 | void main() { 53 | makeSet(50); 54 | int m; // user gives m operations 55 | // eg. union(1,2), union(2,3), union(4,5) etc 56 | cin >> m; 57 | while(m--){ 58 | int u, v; 59 | cin >> u >> v; 60 | union(u,v); 61 | } 62 | 63 | // find if nodes 2 and 3 (assume exists) belong to same component or not 64 | if(findParent(2) != findParent(3)) cout << "Diff components"; 65 | else cout << "Both part of same component"; 66 | 67 | 68 | } 69 | 70 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 24 (Graphs)/Floyd Warshall Algo.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution { 4 | public: 5 | void shortest_distance(vector>&matrix){ 6 | int V = matrix.size(); 7 | // all pairs shortest path 8 | // we consider every node as intermediate btw the 2 pairs of nodes chosen and see if 9 | // they can be reached w a smaller distance thru that intermediate k node 10 | 11 | for(int k = 0; k 4 | using namespace std; 5 | 6 | // Pick greedily the smallest wt node, and check if this node and its connection node share a parent 7 | // using Disjoint Set concept learnt prev. If same parent, then cycle would form. So edge not allowed. 8 | 9 | struct node { // we use a datastructure instead of adj-list to sort in asc. based on wt 10 | int u; 11 | int v; 12 | int wt; 13 | //constructor 14 | node(int first, int second, int weight){ 15 | u = first; 16 | v = second; 17 | wt = weight; 18 | } 19 | }; 20 | 21 | bool comp(node a, node b){ 22 | return a.wt < b.wt; 23 | } 24 | 25 | int findParent(int u, vector &parent){ 26 | if(u == parent[u]) return u; 27 | return parent[u] = findParent(parent[u], parent); 28 | } 29 | 30 | void unionn(int u, int v, vector &parent, vector &rank){ 31 | u = findParent(u, parent); 32 | v = findParent(v, parent); 33 | 34 | if(rank[u] < rank[v]){ 35 | // add u to v 36 | parent[u] = v; 37 | } else if(rank[u] > rank[v]){ 38 | // add v to u 39 | parent[v] = u; 40 | } 41 | 42 | else { 43 | // btoh ranks same. 44 | parent[u] = v; 45 | rank[v]++; 46 | } 47 | } 48 | 49 | 50 | int main() { 51 | int N, m; // nodes and edges count 52 | cin >> N >> m; 53 | vector edges; 54 | for(int i = 0; i> u >> v >> wt; 57 | edges.push_back(node(u,v,wt)); 58 | } 59 | 60 | // sorting by weight 61 | sort(edges.begin(), edges.end(), comp); 62 | 63 | // Disjoint set starts - parent and rank arrays 64 | vector parent(N); 65 | for(int i = 0; i rank(N, 0); 67 | 68 | int cost = 0; // MST cost 69 | vector> mst; 70 | for(auto it: edges){ 71 | // trying to connect it.u and it.v by checking if edge btw them is valid 72 | if(findParent(it.u, parent) != findParent(it.v, parent)){ 73 | // valid 74 | cost += it.wt; 75 | mst.push_back({it.u, it.v}); // adding edge to MST 76 | unionn(it.u, it.v, parent, rank); // unionize these 2 diff components 77 | } 78 | } 79 | 80 | cout << cost << endl; 81 | // final MST 82 | for(auto it: mst){ 83 | cout << it.first << "--" << it.second << endl; 84 | } 85 | return 0; 86 | 87 | } 88 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 24 (Graphs)/Prim's Algo.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution 4 | { 5 | public: 6 | //Function to find sum of weights of edges of the Minimum Spanning Tree. 7 | // We will do this using Prim's Algorithm 8 | // adj[i].first is the adj node and second is weight 9 | int spanningTree(int V, vector> adj[]) 10 | { 11 | // O(N^2) uses array traversal to find min key everytime. 12 | // N*logN uses minheap (priority Q) to pick up min key in logN time. We will do this 13 | 14 | /* we need 3 arrays: 15 | key[] to maintain the weight used to reach that node. Source node has 0 16 | mst[] to maintain if node already visited or not 17 | parent[] to note down parent node of each node. Source node has -1 18 | 19 | When picking a min val from key[] check if its not visited (mst[]) 20 | 21 | */ 22 | 23 | int key[V]; bool mst[V]; int parent[V]; 24 | 25 | // init 26 | for(int i = 0; i, vector > , greater> > pq; 35 | pq.push({0,0}); // 0 val for 0th index 36 | 37 | // do it n-1 times as a MST with n nodes has n-1 edges 38 | for(int cnt = 0; cnt < V-1; cnt++){ 39 | int u = pq.top().second; // this gives node with min key[i] val automatically 40 | pq.pop(); 41 | mst[u] = true; //visited 42 | 43 | for(auto it: adj[u]){ 44 | int v = it[0]; 45 | int wt = it[1]; 46 | if(mst[v] == false && wt < key[v]) { 47 | // update key with new weight (prev it was high (either inf or some big no)) 48 | // and then update parent as u. mst[] changes only when node picked 49 | key[v] = wt; 50 | parent[v] = u; 51 | pq.push({key[v], v}); 52 | } 53 | } 54 | 55 | } 56 | 57 | // traverse key[i] and keep summing to get final wt of MST graph 58 | int sum = 0; 59 | for(int i = 0; i 4 | #define INF INT_MAX 5 | 6 | using namespace std; 7 | 8 | void findTopoSort(int node, int vis[], stack &stk, vector> adj[]){ 9 | // generate topo sort 10 | vis[node] = 1; 11 | for(auto it: adj[node]){ 12 | if(!vis[it.first]) findTopoSort(it.first, vis, stk, adj); 13 | } 14 | stk.push(node); 15 | } 16 | 17 | void shortestPath(int src, int N, vector> adj[]){ 18 | // same as "Shortest Path in Undirected Graph" but we do topological sort first w stack 19 | int vis[N] = {0}; // init the visited array 20 | stack stk; // when all children of a node traversed, put that node here 21 | 22 | for(int i = 0; i> n >> m; 60 | // in directed graph w weights, we use pair to store a node and its weight 61 | vector> adj[n]; 62 | for(int i = 0; i> u >> v >> wt; // u->v is an edge and wt is weight btw the 2 nodes 65 | adj[u]. push_back({v,wt}); 66 | } 67 | 68 | shortestPath(0, n, adj); // source, no of nodes, adj list 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 24 (Graphs)/Shortest Path Undirected Graph.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | void shortestPathBFS(vector adj[], int N, int src){ 4 | // adj is adjacency list of graph, N is # of nodes, src is starting node from which we find min dist to all other nodes 5 | vector dist(N,1000); // initializing dist for all nodes with a big no (INT_MAX). Here, 1000 arbitrarity chosen 6 | queue q; 7 | 8 | dist[src] = 0; 9 | q.push(src); 10 | 11 | while(!q.empty()){ 12 | int curr = q.front(); q.pop(); 13 | 14 | for(auto it: adj[curr]){ 15 | if(dist[curr] + 1 < dist[it]) { 16 | dist[it] = dist[curr] + 1; 17 | q.push(it); 18 | } 19 | } 20 | } 21 | 22 | for(int i = 0; i &stk, vector &vis, vector adj[]){ 11 | vis[curr] = 1; 12 | 13 | for(auto it: adj[curr]){ 14 | if(!vis[it]) dfs(it, stk, vis, adj); 15 | } 16 | 17 | stk.push(curr); 18 | } 19 | 20 | void revDfs(int curr, vector &vis, vector adj[]){ 21 | vis[curr] = 1; 22 | 23 | for(auto it: adj[curr]){ 24 | if(!vis[it]) revDfs(it, vis, adj); 25 | } 26 | } 27 | 28 | 29 | 30 | int kosaraju(int V, vector adj[]) 31 | { 32 | // do topo sort first 33 | stack stk; 34 | int res = 0; 35 | vector vis(V, 0); 36 | for(int i = 0; i transpose[V]; 43 | 44 | for(int i = 0; i will give TLE 5 | class Solution 6 | { 7 | public: 8 | //Function to return max value that can be put in knapsack of capacity W. 9 | int knapSack(int w, int wt[], int val[], int n) 10 | { 11 | // this time we do recursion method (form a recursion tree) 12 | if(n == 0 || w == 0) return 0; // base case when no of items or wt in sack available = 0 13 | if(wt[n] > w) return knapSack(w, wt, val, n-1); // skipped item and w stays same 14 | else { 15 | // if item wt < tot wt, then we can either include or exclude item based on choosing 16 | // which is greater 17 | return max(knapSack(w - wt[n], wt, val, n - 1) + val[n], knapSack(w, wt, val, n - 1)); 18 | } 19 | 20 | } 21 | }; 22 | 23 | // Method 2 24 | // TC and SC : O(m*n) as 2D matrix is used 25 | 26 | class Solution 27 | { 28 | public: 29 | //Function to return max value that can be put in knapsack of capacity W. 30 | int knapSack(int w, int wt[], int val[], int n) 31 | { 32 | // we will do bottom up appoach using 2D matrix 33 | int dp[n+1][w+1]; 34 | memset(dp, 0, sizeof dp); 35 | // rows are value chosen and columns are weights. For each value (row) we will calc 36 | // all values (subproblems). So, last row last column cell has the ans for overall 37 | 38 | for(int i = 0; i<=n; i++){ 39 | for(int j = 0; j<=w; j++) { 40 | if(i == 0 || j == 0) dp[i][j] = 0; 41 | // if curr chosen's wt > max wt available, then top cell's val is assigned 42 | else if(wt[i-1] > j) dp[i][j] = dp[i-1][j]; 43 | else { 44 | // find max btw top ele and val when curr element is chosen into sack 45 | dp[i][j] = max(dp[i-1][j], val[i-1] + dp[i-1][j - wt[i-1]]); 46 | } 47 | } 48 | 49 | } 50 | return dp[n][w]; 51 | } 52 | }; 53 | 54 | // Method 3 (most optimal as TC same as Method 2 but SC is O(w) as only 1D array and not 2D matrix is used) 55 | 56 | class Solution 57 | { 58 | public: 59 | //Function to return max value that can be put in knapsack of capacity W. 60 | int knapSack(int w, int wt[], int val[], int n) 61 | { 62 | // we will do bottom up appoach using 1D array 63 | int dp[w + 1] = {0}; 64 | 65 | for(int i = 0; i= wt[i]; j--){ // item wt can never be > wt available 67 | dp[j] = max(dp[j], val[i] + dp[j - wt[i]]); 68 | } 69 | } 70 | return dp[w]; 71 | } 72 | }; 73 | 74 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 25 (DP)/Edit Distance.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution { 4 | public: 5 | // The Levenshtein Distance Problem [watch BacktoBack SWE's vid before] 6 | // Choose whether to delete, replace or insert a character based on whichever is 7 | // the minimum cost operation. 8 | 9 | // TC and SC - O(a*b) where a and b are lengths of the 2 words 10 | int minDistance(string word1, string word2) { 11 | int a = word1.size(), b = word2.size(); 12 | 13 | // Create a 2D DP table with first element of both row and col as " " (empty string) 14 | // better use 2D vector instead of dp[a+1][b+1] when a and b (var) are used. 15 | // Easier to declare and initialize without errors 16 | vector> dp(a+1, vector (b+1, 0)); 17 | // Say word1 is hari (row) and word2 is haran (col) 18 | // First row of table contain the no. of steps from converting " " (row) into 19 | // " " (col) -> 0, into "h" -> 1, into "ha" -> 2, into "hara" -> 4, into "haran" -> 5 20 | // similarly for First column of table 21 | 22 | for(int i = 0; i<=a; i++) dp[i][0] = i; 23 | for(int j = 0; j<=b; j++) dp[0][j] = j; 24 | 25 | // now fill the remaining elements. 26 | // If i and j letters don't match, take min(left, diag, top) + 1 as curr value 27 | // (Left -> Delete, Diagonal -> Replace, Top -> Insert) costs 28 | 29 | for(int i = 1; i<=a; i++){ 30 | for(int j = 1; j<=b; j++){ 31 | if(word1[i-1] != word2[j-1]) { 32 | dp[i][j] = 1 + min({dp[i][j-1], dp[i-1][j-1], dp[i-1][j]}); // use {} for calc min as > 2 elements are present 33 | } else { 34 | // if words match, just add diagonal ele as curr..just like std 2D DP problems 35 | dp[i][j] = dp[i-1][j-1]; 36 | } 37 | } 38 | } 39 | // Bottom right will have the final # of operations...this is the bottoms up 40 | // approach as we solve smaller subproblems until our big bad ans is calculated! 41 | return dp[a][b]; 42 | 43 | 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 25 (DP)/Longest Common Subsequence.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | int longestCommonSubsequence(string text1, string text2) { 4 | int s1 = text1.size(); 5 | int s2 = text2.size(); 6 | // create a 2D DP matrix with 1 extra row and col (filled w 0) 7 | int dp[s1 + 1][s2 + 1]; 8 | // or can do dp[][] = {0} also 9 | memset(dp, 0, sizeof dp); 10 | 11 | // iterate thru matrix in reverse (Bottom up approach) 12 | for(int i = s1-1; i>=0; i--){ 13 | for(int j = s2-1; j>=0; j--){ 14 | // if ele match, val will be 1 + val at diagonal 15 | if(text1[i] == text2[j]) { 16 | dp[i][j] = 1 + dp[i+1][j+1]; 17 | } 18 | // if ele dont match, max of right and bottom val is assigned 19 | else { 20 | dp[i][j] = max(dp[i+1][j], dp[i][j+1]); 21 | } 22 | } 23 | } 24 | 25 | // first row first col element will have the LCS value 26 | int res = dp[0][0]; 27 | return res; 28 | 29 | } 30 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 25 (DP)/Longest Inc Subsequence.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | // There is a better O(NLogN) answer. Try to understand that in Phase-2 prep 4 | 5 | int lengthOfLIS(vector& nums) { 6 | // start from last element and check if its next ele can be included in subseq 7 | // iff curr ele < next elements 8 | 9 | // O(N^2) as we check for an element, all the elements after it 10 | int N = nums.size(); 11 | int res = 1; 12 | 13 | // all LIS should be min 1 (with self) 14 | vector LIS(N, 1); 15 | for(int i = N-2; i>=0; i--){ 16 | for(int j = i+1; j& nums) { 32 | int lis[100000]; 33 | int n = nums.size(); 34 | for(int i = 0; i < n; i++) 35 | lis[i] = 1; 36 | for(int i = 1; i < n ; i++) 37 | { 38 | for(int j = 0; j < i; j++) 39 | { 40 | if(nums[j] < nums[i]) 41 | { 42 | lis[i] = max(lis[i], lis[j] + 1); 43 | } 44 | } 45 | } 46 | int maxEle = INT_MIN; 47 | for(int i = 0; i < n; i++) 48 | { 49 | maxEle = max(maxEle, lis[i]); 50 | } 51 | return maxEle; 52 | } 53 | }; 54 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 25 (DP)/Matrix Chain Multiplication(Hard).cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution{ 4 | public: 5 | int helper(int i, int j, int arr[], vector> &dp) 6 | { 7 | if(i == j) return 0; // in A(CD) A is a singular ele so 0 is cost of multiplying 8 | int minCost = INT_MAX; 9 | 10 | if(dp[i][j] != -1) return dp[i][j]; // memoization 11 | 12 | for(int k = i; k> dp(N, vector (N, -1)); 32 | // we can divide in N-1 places starting from 1 33 | // A(BCD) , AB(CD), ABC(D) where first ( is at 1,2,3 places resp. ) 34 | return helper(1, N-1, arr, dp); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 25 (DP)/Max Sum Inc Subsequence (MSIS).cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | int maxSumIS(int arr[], int n) 4 | { 5 | // Very similar to LIS. Instead of max length, we find max sum 6 | int res = 0; 7 | int MSIS[n]; 8 | 9 | // assign arr values to MSIS. In LIS we add 1 to incorporate chosen ele being added to 10 | // subsequence. Here, we will add the element value itself to get final max sum 11 | 12 | for(int i = 0; i arr[j] && MSIS[i] < MSIS[j] + arr[i]) { 18 | // then arr[i] can be included in subseq 19 | MSIS[i] = MSIS[j] + arr[i]; 20 | } 21 | } 22 | } 23 | 24 | // final traverse to check max sum 25 | for(int i = 0; i& nums) { 5 | int minProd = 1; 6 | int maxProd = 1; 7 | int result = INT_MIN; 8 | 9 | for(int i = 0; i& nums) { 25 | // we need 2 variables max_ending_here and min_ending_here (for -ve numbers) 26 | int N = nums.size(); 27 | int max_ending_here = nums[0]; 28 | int min_ending_here = nums[0]; 29 | int maxOverall = nums[0]; // return this 30 | 31 | for(int i = 1; i 2 elements to find max, just put everything in {}) 39 | max_ending_here = max({nums[i], max_ending_here * nums[i], 40 | min_ending_here * nums[i]}); 41 | min_ending_here = min(nums[i], min(temp_max_ending_here * nums[i], 42 | min_ending_here * nums[i])); 43 | maxOverall = max(maxOverall, max_ending_here); 44 | } 45 | return maxOverall; 46 | 47 | } 48 | }; 49 | 50 | 51 | // Sid 52 | 53 | class Solution { 54 | public: 55 | int maxProduct(vector& nums) { 56 | int maxProd = nums[0]; 57 | int minProd = nums[0]; 58 | int res = nums[0]; 59 | for(int i = 1; i < nums.size(); i++) 60 | { 61 | int temp = maxProd; 62 | maxProd = max(nums[i], max(nums[i]*maxProd, nums[i]*minProd)); 63 | minProd = min(nums[i], min(temp*nums[i], minProd*nums[i])); 64 | res = max(res, maxProd); 65 | } 66 | 67 | return res; 68 | 69 | } 70 | }; 71 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 26 (DP)/Climbing Stairs.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution { 4 | public: 5 | int climbStairs(int n) { 6 | // DP Method 7 | vector dp(n+1, 0); 8 | if(n == 0 || n == 1 || n == 2) return n; 9 | 10 | dp[0] = 1; // only way to walk 0 stairs is to not walk (1) 11 | dp[1] = 1; 12 | 13 | for(int i = 2; i<=n; i++){ 14 | dp[i] = dp[i-1] + dp[i-2]; 15 | } 16 | return dp[n]; 17 | 18 | 19 | // Fibonacci method - almost the exact same as DP 20 | if(n == 0 || n == 1 || n == 2) return n; // base 21 | int finalWays = 0; 22 | int oneStepBef = 2; 23 | int twoStepsBef = 1; 24 | 25 | for(int i = 2; i& coins, int amount) { 6 | sort(coins.begin(), coins.end()); 7 | // make dp table (1D) for each amount from 0->amount. 8 | // Each will tell min coins needed to attain that particular cell's amount(j) 9 | // Bottom up approach 10 | 11 | vector dp(amount+1, 69696969); 12 | dp[0] = 0; // for 0 amount, 0 coins needed 13 | 14 | for(int i = 1; i<=amount; i++){ 15 | for(int j = 0; j& coins, int amount) { 30 | vector dp(amount + 1, 69696969); 31 | dp[0] = 0; // For 0 amount, 0 coins needed 32 | 33 | for(int i = 0; i= current coin chosen 35 | // so no need if condt to check if coin chosen < j(amount) 36 | dp[j] = min(dp[j], 1 + dp[j - coins[i]]); 37 | } 38 | } 39 | 40 | return dp[amount] == 69696969? -1 : dp[amount]; 41 | } 42 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 26 (DP)/Egg Dropping(Hard).cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | /* 3 | Refer: https://bit.ly/3hbmWuT 4 | Method - 1 -> "Naive" using 2-D (n*k) matrix 5 | Useful for grasping the concept 6 | 7 | */ 8 | 9 | class Solution { 10 | public: 11 | int superEggDrop(int k, int n) { 12 | // k -> no of eggs and n -> no of floors in building 13 | vector> dp(n+1, vector (k+1, 0)); // n x k matrix 14 | 15 | /* 16 | EXPLANATION (n -> floors, e -> eggs count) 17 | 1) F[n][e] = min(max(F[n-x][e], F[x-1][e-1]) + 1) 18 | x = 1->n-1 19 | Minimize the max (worst case) to get least no. of tries to get the right floor. 20 | 21 | F[n-x][e] is when egg doesn't break. e remains same and we need to focus on higher 22 | floors (n-x) 23 | 24 | F[x-1][e-1] is when egg does break. e-1 eggs left. So to find breaking point floor, 25 | we go down (x-1). 26 | 27 | The +1 at the end is for counting the one try (dropping egg) from current floor, 28 | irrespective of whether egg is broken or not 29 | 30 | 2) 2 constraints: F[1][e] = 1 as if we have 1 floor left and any no. of eggs, 31 | only 1 try is possible anyways. F[n][1] = n as if we have n floors to check and 1 egg 32 | left, we start from bottom floor and keep dropping same egg in each higher floor till 33 | it breaks. (worst case n floors) 34 | */ 35 | 36 | for(int i = 0; i> dp(N + 1, vector(K + 1, 0)); 64 | int m = 0; 65 | while (dp[m][K] < N) { 66 | m++; 67 | for (int k = 1; k <= K; ++k) 68 | dp[m][k] = dp[m - 1][k - 1] + dp[m - 1][k] + 1; 69 | } 70 | return m; 71 | } 72 | }; 73 | 74 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 26 (DP)/Max Profit Job scheduling(Hard).cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution { 4 | public: 5 | 6 | int helper(int idx, vector &A, vector &B, vector &C, vector &dp){ 7 | int N = A.size(); 8 | if(idx == N-1) return C[idx]; 9 | if(dp[idx] != -1) return dp[idx]; 10 | // next possible starttime job after idx th job which ends at B[idx] time 11 | auto curr = lower_bound(A.begin()+idx, A.end(), B[idx]); 12 | 13 | int chosen, notchosen; // profit when curr job is chosen and not chosen 14 | 15 | // when the job is chosen 16 | if(curr == A.end()) chosen = C[idx]; // if last job left just assign its profit 17 | else { 18 | chosen = C[idx] + helper(curr-A.begin(), A, B, C, dp); // curr job profit + max profit from next jobs available after curr 19 | } 20 | 21 | // when the job is skipped 22 | notchosen = helper(idx+1, A, B, C, dp); 23 | 24 | return dp[idx] = max(chosen, notchosen); // added max profit to dp table 25 | } 26 | 27 | 28 | static bool comp(vector &A, vector &B){ 29 | if(A[0] == B[0]){ 30 | if(A[1] == B[1]) return A[2] > B[2]; // desc order of profit 31 | return A[1] < B[1]; // asc order of endTime 32 | } 33 | return A[0] < B[0]; // asc order of startTime 34 | } 35 | 36 | 37 | int jobScheduling(vector& startTime, vector& endTime, vector& profit) { 38 | int N = startTime.size(); 39 | vector> AA; // this will help us form startT, endT, profit sorted in right way 40 | for(int i = 0; i dp(N, -1); 57 | return helper(0, startTime, endTime, profit, dp); 58 | } 59 | 60 | }; 61 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 26 (DP)/Max Sum Path in Matrix(2 methods).cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | // Method - 1 larger space using code O(m*n) SC 4 | int minPathSum(vector>& grid) { 5 | int m = grid.size(); 6 | int n = grid[0].size(); 7 | 8 | vector> sumMat(m, vector(n, grid[0][0])); 9 | // find sum val for first row and col 10 | for(int i = 1; i j) dp[i][j] = dp[i-1][j]; 26 | else { 27 | // cuts[i-1] <= j 28 | dp[i][j] = max(dp[i-1][j], 1 + dp[i][j - cuts[i-1]]); // new cut count 29 | } 30 | } 31 | } 32 | } 33 | 34 | return dp[3][n] < 0 ? 0 : dp[3][n]; 35 | } 36 | 37 | // Method - 2 using 1D array 38 | 39 | int maximizeTheCuts(int n, int x, int y, int z) 40 | { 41 | int dp[n+1]; 42 | memset(dp, -1, sizeof dp); 43 | 44 | dp[0] = 0; 45 | 46 | for(int i = 1; i<=n; i++) { 47 | if(i - x >= 0) { 48 | dp[i] = max(dp[i], dp[i - x]); 49 | } 50 | 51 | if(i - y >= 0) { 52 | dp[i] = max(dp[i], dp[i - y]); 53 | } 54 | 55 | if(i - z >= 0) { 56 | dp[i] = max(dp[i], dp[i - z]); 57 | } 58 | 59 | // if one of the above has occured, inc count of cut by 1 60 | if(dp[i] != -1) dp[i] += 1; 61 | } 62 | 63 | return max(0, dp[n]); 64 | // same as return dp[n] == -1 ? 0 : dp[n]; 65 | } 66 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 26 (DP)/Subset Sum.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | int Solution::solve(vector &A, int B) { 4 | int N = A.size(); 5 | // create a DP table with N+1 rows and B+1 columns 6 | bool dp[N+1][B+1]; 7 | 8 | // First col will be fully true(1)->U can make sum=0 with any element from A ie. 9 | // empty set gives sum 0. 10 | // First row(barring first element) will be false as u cant make sum=column elements 11 | // with no elements in vector A. 12 | 13 | for(int j = 0; j<=B; j++) dp[0][j] = false; 14 | for(int i = 0; i<=N; i++) dp[i][0] = true; 15 | 16 | for(int i = 1; i<=N; i++){ 17 | for(int j = 1; j<=B; j++){ 18 | if(A[i-1] > j) dp[i][j] = dp[i-1][j]; // if ele of A chosen > curr sum ele of B 19 | else { 20 | dp[i][j] = dp[i-1][j] || dp[i-1][j-A[i-1]]; 21 | // OR gives max btw both bools. First term is when ele of A not chosen. 22 | // Second is if its chosen, subtract that val from sum and see state of 23 | //resultant element value 24 | } 25 | } 26 | } 27 | 28 | return (int)dp[N][B]; //bottom rightmost element gives final ans (0->F 1->T) 29 | 30 | } 31 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 26 (DP)/Word Break.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | // Important Problem 3 | 4 | class Solution { 5 | public: 6 | /* 7 | dp[i] = true if a word ends at the i th pos. 8 | Optimized soln is to look from current idx back until the pos with dp[pos] = true 9 | and then find the substring btw pos and current, and then check if this exists in wordDict 10 | 11 | If it does, then dp[curr] = true. 12 | 13 | Also, we use set to store words instead of vector we are given with, as set lookup O(logN) 14 | but vector is O(N). Set uses redblack trees to lookup faster 15 | 16 | */ 17 | 18 | bool wordBreak(string s, vector& wordDict) { 19 | unordered_set uSet(wordDict.begin(), wordDict.end()); 20 | int N = s.size(); 21 | 22 | //for(auto it: wordDict) uSet.insert(it); -> also can be done 23 | 24 | 25 | vector dp(N+1, false); 26 | dp[0] = true; // empty string is a subset of all strings and can be formed with any wordDict 27 | 28 | for(int i = 1; i<=N; i++){ 29 | for(int j = i-1; j>=0; j--){ 30 | if(dp[j]){ 31 | // so we have found a j index with true val 32 | // find substring 33 | string newWord = s.substr(j, i-j); 34 | if(uSet.find(newWord) != uSet.end()) { 35 | // this word is found in set of words given. So mark the wordending index = True 36 | dp[i] = true; 37 | break; // go to next i 38 | } 39 | } 40 | } 41 | } 42 | 43 | return dp[N]; 44 | } 45 | }; 46 | 47 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 3 (Arrays&Math)/Majority Element - 2.cpp: -------------------------------------------------------------------------------- 1 | // Majority Element when > N/3. In prev qn, as it was N/2 the max no. of distinct elements w floor(N/2) occurence is 1 [0-1] 2 | // Here, max no can be 2 elements [0-2] 3 | 4 | class Solution { 5 | public: 6 | vector majorityElement(vector& nums) { 7 | int N = nums.size(); 8 | int count1 = 0, count2 = 0, candidate1 = -1, candidate2 = -1; 9 | 10 | for(int i = 0; i ans; 30 | int c1 = 0, c2 = 0; 31 | for(int i = 0; i N/3) ans.push_back(candidate1); 36 | if(c2 > N/3) ans.push_back(candidate2); 37 | 38 | return ans; 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 3 (Arrays&Math)/Majority Element.cpp: -------------------------------------------------------------------------------- 1 | // Majority Element (>N/2 times) 2 | // One method is using Hashmap as usual. The most optimized method is MOORE'S VOTNG ALGORITHM 3 | 4 | class Solution { 5 | public: 6 | int majorityElement(vector& nums) { 7 | // Moore Voting algo 8 | int count = 0 , candidate = 0; 9 | 10 | for(int t: nums){ 11 | if(count == 0) candidate = t; 12 | if(candidate == t) count++; 13 | else count--; 14 | } 15 | return candidate; 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 3 (Arrays&Math)/Search 2-D Matrix.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | bool searchMatrix(vector>& matrix, int target) { 4 | // abstract binary search method O(n*m), O(1) -> TLE 5 | if(!matrix.size()) return false; 6 | 7 | int rows = matrix.size(); int cols = matrix[0].size(); 8 | int lo = 0, hi = (rows*cols) - 1; 9 | 10 | while(lo <= hi){ 11 | int mid = (lo+(hi-lo)) / 2; 12 | //int indexRow = mid/cols; int indexCol = mid%cols; 13 | if(matrix[mid/cols][mid%cols] == target) return true; 14 | 15 | else if(matrix[mid/cols][mid%cols] < target) lo = mid+1; 16 | else hi = mid-1; 17 | } 18 | return false; 19 | } 20 | 21 | // Manually moving method -> Works perfectly 22 | // int i = 0, j = cols-1; 23 | // while(i < rows && j >= 0){ 24 | // if(matrix[i][j] == target) return true; 25 | // else if(matrix[i][j] < target) i++; 26 | // else j--; 27 | // } 28 | // return false; 29 | // } 30 | }; 31 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 3 (Arrays&Math)/Unique Paths.cpp: -------------------------------------------------------------------------------- 1 | // Decently optimized method is using standard DP to store no of ways of entring that particular coordinate, and using it instead of calculating again next time. 2 | // This one is based on the basic no. of combinations needed to reach END from START -> Combinatorics Method -> O(m-1) or O(n-1), O(1) 3 | 4 | class Solution { 5 | public: 6 | int uniquePaths(int m, int n) { 7 | int N = m+n-2; // (m-1)+(n-1) is the total no. of indexes of combinations 8 | // ie. n in nCr 9 | int r = m-1; // can be n-1 also 10 | //now we find nCr 11 | double ans = 1; 12 | for(int i = 1; i<=r; i++){ 13 | ans = ans * (N-r+i)/i; 14 | } 15 | return (int) ans; 16 | } 17 | }; 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 3 (Arrays&Math)/pow(X,n).cpp: -------------------------------------------------------------------------------- 1 | // Fast Exponential algorithm 2 | 3 | class Solution { 4 | public: 5 | double myPow(double x, int n) { 6 | double ans = 1.0; 7 | long long nn = n; 8 | if(nn < 0) nn = -1 * nn; 9 | 10 | while(nn){ // till its not 0 11 | if(nn%2 == 0){ // even power 12 | x = x * x; 13 | nn /= 2; 14 | } 15 | else { // odd power 16 | ans = ans * x; 17 | nn -= 1; 18 | } 19 | } 20 | if(n < 0) ans = (double)1.0 / (double) ans; 21 | return ans; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 4 (Hashing)/2 Sum.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector twoSum(vector& nums, int target) { 4 | vector> x; 5 | int n = nums.size(); 6 | for(int i = 0; i < n; i++) 7 | { 8 | x.push_back(make_pair(nums[i], i)); 9 | } 10 | sort(x.begin(), x.end()); 11 | int l = 0; 12 | int r = n-1; 13 | vector res; 14 | while(l < r) 15 | { 16 | if(x[l].first + x[r].first == target) 17 | { 18 | res.push_back(x[l].second); 19 | res.push_back(x[r].second); 20 | break; 21 | } 22 | else if(x[l].first + x[r].first > target) 23 | r--; 24 | else 25 | l++; 26 | } 27 | sort(res.begin(), res.end()); 28 | return res; 29 | } 30 | }; 31 | 32 | // Hari's 33 | class Solution { 34 | public: 35 | vector twoSum(vector& nums, int target) { 36 | vector> vec; 37 | vector res; 38 | for(int i = 0; i> fourSum(vector& nums, int target) { 4 | sort(nums.begin(), nums.end()); 5 | int n = nums.size(); 6 | set> set1; 7 | for(int i = 0; i < n-1; i++) 8 | { 9 | vector temp; 10 | for(int j = i+1; j < n; j++) 11 | { 12 | int l = j+1; 13 | int r = n - 1; 14 | int sum = target - nums[i] - nums[j]; 15 | while(l < r) 16 | { 17 | if(nums[l] + nums[r] == sum) 18 | { 19 | temp.push_back(nums[i]); 20 | temp.push_back(nums[j]); 21 | temp.push_back(nums[l]); 22 | temp.push_back(nums[r]); 23 | set1.insert(temp); 24 | temp.clear(); 25 | l++; 26 | r--; 27 | } 28 | else if(nums[l] + nums[r] > sum) 29 | r--; 30 | else 31 | l++; 32 | } 33 | } 34 | } 35 | vector> res; 36 | for(auto it = set1.begin(); it != set1.end(); it++) 37 | { 38 | res.push_back(*it); 39 | } 40 | return res; 41 | } 42 | }; 43 | 44 | 45 | // Hari's 46 | 47 | class Solution { 48 | public: 49 | vector> fourSum(vector& nums, int target) { 50 | sort(nums.begin(), nums.end()); 51 | vector> ans; 52 | set> s; 53 | int N = nums.size(); 54 | 55 | for(int i = 0; i temp; 57 | for(int j = i+1; j m; // sum, index 6 | int sum = 0, maxLen = 0; 7 | 8 | for(int i = 0; i m; 34 | int length = 0; 35 | for(int i = 0; i < n+1; i++) 36 | { 37 | if(m[sum[i]] == 0) 38 | { 39 | m[sum[i]] = i+1; 40 | } 41 | else 42 | { 43 | length = max(length, i + 1 - m[sum[i]]); 44 | } 45 | } 46 | return length; 47 | } 48 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 4 (Hashing)/Longest Consecutive Sequence.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int longestConsecutive(vector& nums) { 4 | if(nums.size() == 0) 5 | return 0; 6 | int l = 0; 7 | int r = 1; 8 | set s; 9 | for(int i = 0; i < nums.size(); i++) 10 | s.insert(nums[i]); 11 | 12 | vector nums1; 13 | for(auto it = s.begin(); it != s.end(); it++) 14 | { 15 | nums1.push_back(*it); 16 | } 17 | int maxL = 1; 18 | while(l < nums1.size() && r < nums1.size()) 19 | { 20 | if(nums1[r] - nums1[r-1] == 1) 21 | { 22 | r++; 23 | } 24 | else 25 | { 26 | maxL = max(maxL, r - l); 27 | l = r; 28 | r++; 29 | } 30 | } 31 | maxL = max(maxL, r - l); 32 | return maxL; 33 | } 34 | }; 35 | 36 | // Hari's 37 | 38 | class Solution { 39 | public: 40 | int longestConsecutive(vector& nums) { 41 | set hashSet; 42 | for(auto it: nums) hashSet.insert(it); 43 | 44 | int maxStreak = 0; 45 | for(int it: nums){ 46 | if(!hashSet.count(it-1)){ 47 | // if "it" is the smallest no. in a seq, start count from that "it" 48 | int currNum = it, currStreak = 1; 49 | 50 | while(hashSet.count(currNum+1)){ 51 | currNum = currNum+1; 52 | currStreak += 1; 53 | maxStreak = max(maxStreak, currStreak); 54 | } 55 | maxStreak = max(maxStreak, currStreak); 56 | } 57 | } 58 | return maxStreak; 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 5 (Linked List)/Add 2 Linked List Numbers.cpp: -------------------------------------------------------------------------------- 1 | // Hari's 2 | 3 | class Solution { 4 | public: 5 | ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { 6 | ListNode *newL = new ListNode(0); 7 | ListNode *res = newL; 8 | int carry = 0; 9 | while(l1 != nullptr && l2 != nullptr){ 10 | int sum = l1->val + l2->val + carry; 11 | res->next = new ListNode(sum % 10); 12 | carry = sum / 10; 13 | l1 = l1->next; 14 | l2 = l2->next; 15 | res = res->next; 16 | } 17 | 18 | while(l1 != nullptr){ 19 | int sum = l1->val + carry; 20 | res->next = new ListNode(sum % 10); 21 | carry = sum / 10; 22 | l1 = l1->next; 23 | res = res->next; 24 | } 25 | 26 | while(l2 != nullptr){ 27 | int sum = l2->val + carry; 28 | res->next = new ListNode(sum % 10); 29 | carry = sum / 10; 30 | l2 = l2->next; 31 | res = res->next; 32 | } 33 | 34 | if(carry != 0){ 35 | res->next = new ListNode(carry); 36 | } 37 | return newL->next; 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 5 (Linked List)/Delete Node In A Linked List.cpp: -------------------------------------------------------------------------------- 1 | //Sid's solution 2 | class Solution { 3 | public: 4 | void deleteNode(ListNode* node) { 5 | ListNode *cur = node; 6 | ListNode *prev; 7 | while(cur->next != NULL) 8 | { 9 | prev = cur; 10 | cur->val = cur->next->val; 11 | cur = cur->next; 12 | } 13 | prev->next = NULL; 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 5 (Linked List)/Merge Two Sorted Lists.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * struct ListNode { 4 | * int val; 5 | * ListNode *next; 6 | * ListNode() : val(0), next(nullptr) {} 7 | * ListNode(int x) : val(x), next(nullptr) {} 8 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 9 | * }; 10 | */ 11 | class Solution { 12 | public: 13 | ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { 14 | ListNode *l3 = new ListNode(0); 15 | ListNode *dummy = l3; 16 | while(l1 != NULL && l2 != NULL) 17 | { 18 | if(l1->val > l2->val) 19 | { 20 | l3->next = l2; 21 | l2 = l2->next; 22 | } 23 | else 24 | { 25 | l3->next = l1; 26 | l1 = l1->next; 27 | } 28 | l3 = l3->next; 29 | } 30 | if(l1) 31 | l3->next = l1; 32 | if(l2) 33 | l3->next = l2; 34 | return dummy->next; 35 | } 36 | }; 37 | 38 | 39 | // Hari's 40 | 41 | class Solution { 42 | public: 43 | ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { 44 | ListNode *ans = new ListNode(0); 45 | ListNode *res = ans; 46 | while(l1 != nullptr && l2 != nullptr){ 47 | if(l1->val < l2->val){ 48 | res->next = l1; 49 | l1 = l1->next; 50 | } 51 | else if(l1->val >= l2->val){ 52 | res->next = l2; 53 | l2 = l2->next; 54 | } 55 | res = res->next; 56 | } 57 | 58 | if(l1 != nullptr){ 59 | res->next = l1; 60 | } 61 | 62 | if(l2 != nullptr){ 63 | res->next = l2; 64 | } 65 | 66 | return ans->next; 67 | } 68 | }; 69 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 5 (Linked List)/Middle Of Linked List.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * struct ListNode { 4 | * int val; 5 | * ListNode *next; 6 | * ListNode() : val(0), next(nullptr) {} 7 | * ListNode(int x) : val(x), next(nullptr) {} 8 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 9 | * }; 10 | */ 11 | class Solution { 12 | public: 13 | ListNode* reverseList(ListNode* head) { 14 | ListNode *cur = head; 15 | ListNode *prev = NULL; 16 | ListNode *ptr = head; 17 | while(cur != NULL) 18 | { 19 | ListNode *temp = cur->next; 20 | cur->next = prev; 21 | prev = cur; 22 | cur = temp; 23 | } 24 | return prev; 25 | } 26 | }; 27 | 28 | // Hari's 29 | 30 | class Solution { 31 | public: 32 | ListNode* middleNode(ListNode* head) { 33 | ListNode *fast = head; 34 | ListNode *slow = head; 35 | 36 | while(fast != nullptr && fast->next != nullptr){ 37 | fast = fast->next->next; 38 | slow = slow->next; 39 | } 40 | return slow; 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 5 (Linked List)/Remove Nth Node from End of List.cpp: -------------------------------------------------------------------------------- 1 | //Hari's 2 | 3 | class Solution { 4 | public: 5 | ListNode* removeNthFromEnd(ListNode* head, int n) { 6 | ListNode *slow = head; 7 | ListNode *fast = head; 8 | while(n--){ 9 | fast = fast->next; 10 | } 11 | if(fast == nullptr) return slow->next; 12 | 13 | while(fast->next != nullptr){ 14 | fast = fast->next; 15 | slow = slow->next; 16 | } 17 | 18 | slow->next = slow->next->next; 19 | return head; 20 | 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 5 (Linked List)/Reverse Linked List.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * struct ListNode { 4 | * int val; 5 | * ListNode *next; 6 | * ListNode() : val(0), next(nullptr) {} 7 | * ListNode(int x) : val(x), next(nullptr) {} 8 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 9 | * }; 10 | */ 11 | class Solution { 12 | public: 13 | ListNode* reverseList(ListNode* head) { 14 | ListNode *curr = head; 15 | ListNode *prev = nullptr; 16 | 17 | while(curr != nullptr){ 18 | ListNode *temp = curr->next; 19 | curr->next = prev; 20 | prev = curr; 21 | curr = temp; 22 | } 23 | return prev; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 6 (Linked List)/Find The Starting Point Of Loop.cpp: -------------------------------------------------------------------------------- 1 | //Siddharth's solution 2 | /** 3 | * Definition for singly-linked list. 4 | * struct ListNode { 5 | * int val; 6 | * ListNode *next; 7 | * ListNode(int x) : val(x), next(NULL) {} 8 | * }; 9 | */ 10 | class Solution { 11 | public: 12 | ListNode *detectCycle(ListNode *head) { 13 | if(head == NULL || head->next == NULL) 14 | return NULL; 15 | ListNode *slow = head; 16 | ListNode *fast = head; 17 | while(slow != NULL && fast != NULL && fast->next != NULL) 18 | { 19 | slow = slow->next; 20 | fast = fast->next->next; 21 | if(slow == fast) 22 | break; 23 | } 24 | if(slow != fast) 25 | return NULL; 26 | slow = head; 27 | while(slow != fast) 28 | { 29 | slow = slow->next; 30 | fast = fast->next; 31 | } 32 | return slow; 33 | } 34 | }; 35 | 36 | 37 | // Hari's 38 | 39 | class Solution { 40 | public: 41 | ListNode *detectCycle(ListNode *head) { 42 | ListNode *slow = head, *fast = head; 43 | 44 | while(slow && fast && fast->next){ 45 | slow = slow->next; 46 | fast = fast->next->next; 47 | 48 | if(slow == fast){ 49 | while(slow && head){ 50 | if(slow == head) return slow; 51 | else { 52 | slow = slow->next; 53 | head = head->next; 54 | } 55 | } 56 | } 57 | } 58 | return nullptr; 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 6 (Linked List)/Intersection of 2 LinkedLists.cpp: -------------------------------------------------------------------------------- 1 | // Hari's 2 | 3 | class Solution { 4 | public: 5 | int counter(ListNode *head){ 6 | ListNode *curr = head; 7 | int count = 0; 8 | 9 | while(curr != nullptr){ 10 | count++; 11 | curr = curr->next; 12 | } 13 | return count; 14 | } 15 | 16 | ListNode *findInter(ListNode *headA, ListNode *headB, int diff){ 17 | // moved headA by diff so starting point is same 18 | ListNode *currA = headA; 19 | ListNode *currB = headB; 20 | 21 | for(int i = 0; inext; 24 | } 25 | 26 | while(currA != nullptr && currB != nullptr){ 27 | if(currA == currB) return currA; 28 | 29 | currA = currA->next; 30 | currB = currB->next; 31 | } 32 | return nullptr; 33 | } 34 | 35 | ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { 36 | int lenA = counter(headA); 37 | int lenB = counter(headB); 38 | 39 | int d = abs(lenA - lenB); 40 | if(lenA > lenB){ 41 | return findInter(headA, headB, d); 42 | } 43 | else return findInter(headB, headA, d); 44 | } 45 | }; 46 | 47 | //Siddharth's solution 48 | 49 | /** 50 | * Definition for singly-linked list. 51 | * struct ListNode { 52 | * int val; 53 | * ListNode *next; 54 | * ListNode(int x) : val(x), next(NULL) {} 55 | * }; 56 | */ 57 | class Solution { 58 | public: 59 | int getSize(ListNode *head) 60 | { 61 | ListNode *ptr = head; 62 | int size = 0; 63 | while(ptr != NULL) 64 | { 65 | size++; 66 | ptr = ptr->next; 67 | } 68 | return size; 69 | } 70 | ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { 71 | int a = getSize(headA); 72 | int b = getSize(headB); 73 | ListNode *ptra = headA; 74 | ListNode *ptrb = headB; 75 | if(a > b) 76 | { 77 | int c = a-b; 78 | while(ptra != NULL && c--) 79 | { 80 | ptra = ptra->next; 81 | } 82 | } 83 | else 84 | { 85 | int c = b - a; 86 | while(ptrb != NULL && c--) 87 | { 88 | ptrb = ptrb->next; 89 | } 90 | } 91 | while(ptra != NULL && ptrb != NULL) 92 | { 93 | if(ptra == ptrb) 94 | return ptra; 95 | ptra = ptra->next; 96 | ptrb = ptrb->next; 97 | } 98 | return NULL; 99 | } 100 | }; 101 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 6 (Linked List)/Linked List Cycle.cpp: -------------------------------------------------------------------------------- 1 | // Hari's 2 | class Solution { 3 | public: 4 | bool hasCycle(ListNode *head) { 5 | ListNode *slow = head, *fast = head; 6 | 7 | while(slow && fast && fast->next){ 8 | slow = slow->next; 9 | fast = fast->next->next; 10 | 11 | if(slow == fast) return 1; 12 | } 13 | return 0; 14 | } 15 | }; 16 | 17 | //Sid's solution 18 | 19 | /** 20 | * Definition for singly-linked list. 21 | * struct ListNode { 22 | * int val; 23 | * ListNode *next; 24 | * ListNode(int x) : val(x), next(NULL) {} 25 | * }; 26 | */ 27 | class Solution { 28 | public: 29 | bool hasCycle(ListNode *head) { 30 | ListNode *fast = head; 31 | ListNode *slow = head; 32 | while(slow != NULL && fast != NULL && fast->next != NULL) 33 | { 34 | slow = slow->next; 35 | fast = fast->next->next; 36 | //check after changing both of them as initially both are the same 37 | if(slow == fast) 38 | return true; 39 | } 40 | return false; 41 | } 42 | 43 | }; 44 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 6 (Linked List)/Palindrome Linked List.cpp: -------------------------------------------------------------------------------- 1 | // Hari's 2 | 3 | class Solution { 4 | public: 5 | bool isPalindrome(ListNode* head) { 6 | ListNode *curr = head; 7 | stack stk; 8 | 9 | while(curr != nullptr){ 10 | stk.push(curr->val); 11 | curr = curr->next; 12 | } 13 | 14 | while(head != nullptr){ 15 | int Top = stk.top(); stk.pop(); 16 | if(Top != head->val) return false; 17 | head = head->next; 18 | } 19 | return true; 20 | } 21 | }; 22 | 23 | //Siddharth's solution 24 | /** 25 | * Definition for singly-linked list. 26 | * struct ListNode { 27 | * int val; 28 | * ListNode *next; 29 | * ListNode() : val(0), next(nullptr) {} 30 | * ListNode(int x) : val(x), next(nullptr) {} 31 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 32 | * }; 33 | */ 34 | class Solution { 35 | public: 36 | bool helper(ListNode **left, ListNode *right) 37 | { 38 | if(*left == NULL || right == NULL) 39 | return true; 40 | bool remaining = helper(&(*left), right->next); 41 | if(remaining) 42 | { 43 | if((*left)->val == right->val) 44 | { 45 | (*left) = (*left)->next; 46 | return true; 47 | } 48 | return false; 49 | } 50 | else 51 | { 52 | return false; 53 | } 54 | } 55 | bool isPalindrome(ListNode* head) { 56 | ListNode *left = head; 57 | ListNode *right = head; 58 | return helper(&left, right); 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 6 (Linked List)/Reverse Nodes In K Group.cpp: -------------------------------------------------------------------------------- 1 | //Siddharth's solution 2 | /** 3 | * Definition for singly-linked list. 4 | * struct ListNode { 5 | * int val; 6 | * ListNode *next; 7 | * ListNode() : val(0), next(nullptr) {} 8 | * ListNode(int x) : val(x), next(nullptr) {} 9 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | int getSize(ListNode *head) 15 | { 16 | ListNode *ptr = head; 17 | int size = 0; 18 | while(ptr != NULL) 19 | { 20 | size++; 21 | ptr = ptr->next; 22 | } 23 | return size; 24 | } 25 | ListNode* reverseKGroup(ListNode* head, int k) { 26 | if(head == NULL || head->next == NULL) 27 | return head; 28 | if(k > getSize(head)) 29 | return head; 30 | ListNode *ptr = head; 31 | ListNode *prev = NULL; 32 | ListNode *cur = head; 33 | int c = 0; 34 | while(cur != NULL && c < k) 35 | { 36 | ListNode *temp = cur->next; 37 | cur->next = prev; 38 | prev = cur; 39 | cur = temp; 40 | c++; 41 | } 42 | ptr->next = reverseKGroup(cur, k); 43 | return prev; 44 | } 45 | }; 46 | 47 | //Iterative soln 48 | class Solution { 49 | public: 50 | ListNode *reverseKGroup(ListNode *head, int k) { 51 | if(head==NULL||k==1) return head; 52 | int num=0; 53 | ListNode *preheader = new ListNode(-1); 54 | preheader->next = head; 55 | ListNode *cur = preheader, *nex, *tmp, *pre = preheader; 56 | while(cur = cur->next) 57 | num++; 58 | while(num>=k) { 59 | cur = pre->next; 60 | nex = cur->next; 61 | for(int i=1;inext; 63 | nex->next = pre->next; 64 | pre->next = nex; 65 | cur->next = tmp; 66 | nex = tmp; 67 | } 68 | pre = cur; 69 | num-=k; 70 | } 71 | return preheader->next; 72 | } 73 | }; 74 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 7 (2 pointer)/Clone A Linked List With Random And Next Pointer.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | Node* copyRandomList(Node* head) { 4 | if(head == NULL) 5 | return NULL; 6 | Node *copy, *start = head; 7 | while(start != NULL) 8 | { 9 | Node *temp = start->next; 10 | start->next = new Node(start->val); 11 | start->next->next = temp; 12 | start = temp; 13 | } 14 | start = head; 15 | while(start != NULL) 16 | { 17 | if(start->next != NULL) 18 | start->next->random = start->random? start->random->next: start->random; 19 | start = start->next? start->next->next: start->next; 20 | } 21 | Node *original = head; 22 | copy = head->next; 23 | Node *temp = copy; 24 | while(original != NULL && copy != NULL) 25 | { 26 | original->next = original->next? original->next->next: original->next; 27 | copy->next = copy->next? copy->next->next: copy->next; 28 | original = original->next; 29 | copy = copy->next; 30 | } 31 | return temp; 32 | 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 7 (2 pointer)/Max Consecutive Ones.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | int findMaxConsecutiveOnes(vector& nums) { 4 | int count = 0; 5 | int maxVal = 0; 6 | 7 | for(int i = 0; i& nums) { 2 | int j = 0; 3 | for(int i = 0; i& height) { 4 | int l[100000]; //to hold the maximum values in the left side 5 | int r[100000]; // to hold the maximum values in the right side 6 | int maxL = INT_MIN; 7 | int maxR = INT_MIN; 8 | int n = height.size(); 9 | //travel from left to right 10 | for(int i = 0; i < n; i++) 11 | { 12 | if(height[i] > maxL) 13 | maxL = height[i]; 14 | l[i] = maxL; 15 | } 16 | //travel from right to left 17 | for(int i = n-1; i >= 0; i--) 18 | { 19 | if(height[i] > maxR) 20 | maxR = height[i]; 21 | r[i] = maxR; 22 | } 23 | int area = 0; // the resulting amount of water trapped 24 | for(int i = 0; i < n; i++) 25 | { 26 | area += (min(l[i],r[i])-height[i]); 27 | } 28 | return area; 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 8 (Greedy)/Coin Change.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | //DP solution 4 | int coinChange(vector& coins, int amount) { 5 | int dp[amount + 1]; 6 | sort(coins.begin(), coins.end(), greater()); 7 | dp[0] = 0; // no. of coins for amount = 0 is 0 8 | for(int i = 1; i<=amount; i++) dp[i] = INT_MAX; 9 | 10 | int N = coins.size(); 11 | 12 | for(int i = 1; i<= amount; i++){ 13 | for(int j = 0; j& coins, int amount) { 27 | int count = 0; 28 | sort(coins.begin(), coins.end()); 29 | if(amount == 0) return 0; 30 | int N = coins.size(); 31 | for(int i = N-1; i>=0; i--){ 32 | while(amount >= coins[i]){ 33 | count++; 34 | amount -= coins[i]; 35 | } 36 | } 37 | if(count == 0 || amount > 0) return -1; 38 | return count; 39 | } 40 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 8 (Greedy)/Fractional Knapsack.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution 4 | { 5 | public: 6 | //Function to get the maximum total value in the knapsack. 7 | static bool comp(Item a, Item b){ 8 | double r1 = (double)a.value / (double)a.weight; // double as val may come in decimal. 9 | double r2 = (double)b.value / (double)b.weight; // double as val may come in decimal. 10 | return r1 > r2; 11 | } 12 | double fractionalKnapsack(int W, Item arr[], int n) 13 | { 14 | sort(arr, arr+n, comp); 15 | int currWt = 0; 16 | double finalVal = 0.0; 17 | 18 | for(int i = 0; i b.profit); 5 | } 6 | 7 | vector JobScheduling(Job arr[], int n) 8 | { 9 | // your code here 10 | vector ans; 11 | sort(arr, arr+n, compareProfit); 12 | long count = 0, totProfit = 0; 13 | long maxi = arr[0].dead; 14 | for(int i = 1; i slots(-1, maxi+1); 17 | for(int i = 0; i0; j--){ 19 | if(slots[j] == -1){ 20 | slots[j] = i; 21 | count++; 22 | totProfit += arr[i].profit; 23 | break; 24 | } 25 | } 26 | } 27 | 28 | ans.push_back(count); 29 | ans.push_back(totProfit); 30 | return ans; 31 | } 32 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 8 (Greedy)/Minimum Platforms.cpp: -------------------------------------------------------------------------------- 1 | //Sid's 2 | int findPlatform(int arr[], int dep[], int n) 3 | { 4 | int i = 0, j = 0, plat = 0; 5 | sort(arr,arr+n); 6 | sort(dep,dep+n); 7 | int maxP = INT_MIN; 8 | while(i < n && j < n) 9 | { 10 | if(arr[i] <= dep[j]) 11 | { 12 | plat++; 13 | i++; 14 | } 15 | else 16 | { 17 | plat--; 18 | j++; 19 | } 20 | maxP = max(maxP, plat); 21 | } 22 | return maxP; 23 | } 24 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 8 (Greedy)/N meetings in one room.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | public: 4 | static bool sortbysec(pair &a, pair &b) 5 | { 6 | return (a.second < b.second); 7 | } 8 | 9 | //Function to find the maximum number of meetings that can 10 | //be performed in a meeting room. 11 | int maxMeetings(int start[], int end[], int n) 12 | { 13 | vector> meet; 14 | for(int i = 0; i endTimePrev) { 23 | count++; 24 | endTimePrev = meet[i].second; 25 | } 26 | } 27 | return count; 28 | } 29 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 9 (Recursion)/Combination Sum-1.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | void findCombi(int index, int target, vector& arr, 4 | vector> &ans, vector &ds){ 5 | 6 | if(index == arr.size()) { // all candidates traversed - base case 7 | // after traversing all, target = 0. So eligible candidates are in ds now 8 | if(target == 0) ans.push_back(ds); 9 | return; 10 | } 11 | 12 | //pick up element 13 | if(arr[index] <= target){ 14 | ds.push_back(arr[index]); 15 | findCombi(index, target-arr[index], arr, ans, ds); 16 | // index same as MORE than once can be chosen 17 | // after reaching till end when coming back, remove this element from ds 18 | ds.pop_back(); 19 | 20 | } 21 | 22 | // not picking element 23 | findCombi(index+1, target, arr, ans, ds); 24 | } 25 | 26 | vector> combinationSum(vector& candidates, int target) { 27 | // any qn like this, though process goes to Pick and Not Pick Recursion Method 28 | vector> ans; 29 | vector ds; //holds current iteration chosen values 30 | findCombi(0, target, candidates, ans, ds); 31 | return ans; 32 | } 33 | 34 | //Sid 35 | 36 | class Solution { 37 | public: 38 | void helper(vector candidates, int target, int i, int sum, set> &res, vector r) 39 | { 40 | if(i == candidates.size()) 41 | return; 42 | if(sum == target) 43 | { 44 | res.insert(r); 45 | return; 46 | } 47 | if(sum > target) 48 | return; 49 | helper(candidates, target, i+1, sum, res, r); 50 | r.push_back(candidates[i]); 51 | helper(candidates, target, i, sum+candidates[i], res, r); 52 | } 53 | vector> combinationSum(vector& candidates, int target) { 54 | set> res; 55 | vector r; 56 | sort(candidates.begin(), candidates.end()); 57 | vector candidate; 58 | for(int i = 0; i < candidates.size(); i++) 59 | { 60 | while(i < candidates.size()-1 && candidates[i] == candidates[i+1]) 61 | i++; 62 | candidate.push_back(candidates[i]); 63 | } 64 | helper(candidate, target, 0, 0, res, r); 65 | vector> result; 66 | for(auto it = res.begin(); it != res.end(); it++) 67 | { 68 | result.push_back(*it); 69 | } 70 | return result; 71 | } 72 | }; 73 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 9 (Recursion)/Combination Sum-2.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | void findCombi(int ind, int target, vector &candidates, 4 | vector> &ans, vector &ds){ 5 | 6 | if(target == 0){ // base case. We found a valid combination 7 | ans.push_back(ds); 8 | return; 9 | } 10 | 11 | for(int i = ind; i ind && candidates[i] == candidates[i-1]) continue; // to avoid 13 | //adding same element to ds ie. forming 2 ds of same elements 14 | if(candidates[i] > target) break; // no need to pursue as all candidates 15 | //after current will also be > target. 16 | 17 | // if all condt pass and element is valid 18 | ds.push_back(candidates[i]); 19 | //next call 20 | findCombi(i+1, target-candidates[i], candidates, ans, ds); 21 | // on return from this call, remove added candidates[i] so that we can try diff branch of recursion tree without curr element in it 22 | ds.pop_back(); 23 | } 24 | } 25 | 26 | 27 | vector> combinationSum2(vector& candidates, int target) { 28 | sort(candidates.begin(), candidates.end()); 29 | vector> ans; 30 | vector ds; // datastructure to hold current interation elements 31 | findCombi(0, target, candidates, ans, ds); 32 | return ans; 33 | } 34 | 35 | //Sid 36 | 37 | class Solution { 38 | public: 39 | void helper(vector a, int target, vector> &res, vector r, int sum, int i) 40 | { 41 | if(sum == target) 42 | res.push_back(r); 43 | if(sum > target) 44 | return; 45 | for(int j = i; j < a.size(); j++) 46 | { 47 | if(j != i && a[j] == a[j-1]) 48 | continue; 49 | r.push_back(a[j]); 50 | helper(a, target, res, r, sum+a[j], j+1); 51 | r.pop_back(); 52 | } 53 | } 54 | vector> combinationSum2(vector& candidates, int target) 55 | { 56 | vector> res; 57 | vector r; 58 | sort(candidates.begin(), candidates.end()); 59 | helper(candidates, target, res, r, 0, 0); 60 | return res; 61 | } 62 | }; 63 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 9 (Recursion)/Palindrome Partitioning.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | class Solution { 4 | public: 5 | // palindrome checking fun 6 | bool isPalindrome(string s, int start, int end){ 7 | while(start <= end){ 8 | if(s[start++] != s[end--]) return false; 9 | } 10 | return true; 11 | } 12 | //helper fun 13 | void part(int ind, string s, vector &path, vector> &res ){ 14 | if(ind == s.size()){ 15 | //base case 16 | res.push_back(path); 17 | return; 18 | } 19 | for(int i = ind; i> partition(string s) { 32 | vector> res; 33 | vectorpath; 34 | part(0, s, path, res); 35 | return res; 36 | } 37 | }; 38 | 39 | //Sid 40 | class Solution { 41 | public: 42 | bool isPalindrome(string s) 43 | { 44 | for(int i = 0; i < s.length(); i++) 45 | { 46 | if(s[i] != s[s.length() - i - 1]) 47 | return false; 48 | } 49 | return true; 50 | } 51 | void partition(vector> &res, vector &x, string s) 52 | { 53 | if(s.length() == 0) 54 | { 55 | res.push_back(x); 56 | } 57 | for(int i = 0; i < s.length(); i++) 58 | { 59 | //take the substring from 0 to i 60 | string beg = s.substr(0, i+1); 61 | if(isPalindrome(beg)) 62 | { 63 | x.push_back(beg); 64 | partition(res, x, s.substr(i+1)); 65 | x.pop_back(); 66 | } 67 | } 68 | } 69 | vector> partition(string s) { 70 | vector> res; 71 | vector x; 72 | partition(res, x, s); 73 | return res; 74 | } 75 | }; 76 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 9 (Recursion)/Permutation Sequence.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | string getPermutation(int n, int k) { 4 | // kth permutation (lexicographically) in n! 5 | int fact = 1; 6 | vector nums; 7 | for(int i = 1; i &arr, int N, vector &sumSubset){ 4 | if(ind == N){ 5 | sumSubset.push_back(sum); //basecase. When pointer reaches end, push sum into vector 6 | return; 7 | } 8 | 9 | // pick element 10 | helper(ind+1, sum+arr[ind], arr, N, sumSubset); 11 | 12 | // not picking element 13 | helper(ind+1, sum, arr, N, sumSubset); 14 | } 15 | 16 | vector subsetSums(vector arr, int N) 17 | { 18 | vector sumSubset; 19 | helper(0,0,arr,N,sumSubset); 20 | sort(sumSubset.begin(), sumSubset.end()); 21 | return sumSubset; 22 | } 23 | -------------------------------------------------------------------------------- /Striver SDE Sheet/Day - 9 (Recursion)/Subset-2.cpp: -------------------------------------------------------------------------------- 1 | // Hari 2 | 3 | void findAllSets(int ind, vector& nums, vector &ds, vector>& ans){ 4 | ans.push_back(ds); 5 | for(int i = ind; i> subsetsWithDup(vector& nums) { 14 | vector> ans; 15 | vectords; // holds current list subset 16 | sort(nums.begin(), nums.end()); 17 | findAllSets(0, nums, ds, ans); 18 | return ans; 19 | } 20 | --------------------------------------------------------------------------------