├── Binary Search ├── Binary Search - STL.cpp ├── Binary Search Template.cpp └── Magnetic Force Between Two Balls.cpp ├── Bit Manipulation ├── Reverse Bits.cpp ├── Single Number II.cpp └── Single Number.cpp ├── DP ├── 1. DP - Climbing Stairs.cpp ├── 10. DP - Stone Game.cpp ├── 11. DP - Egg Drop.cpp ├── 12. DP - Maximal Rectangle.cpp ├── 13. DP - Palindrome Partitioning.cpp ├── 14. DP - Maximum Subarray.cpp ├── 2. DP - Coin Change.cpp ├── 3. DP - Counting Bits.cpp ├── 4. DP - Divisor Game.cpp ├── 5. DP - Jump Game II.cpp ├── 5. DP - Target Sum.cpp ├── 6. DP - Pascal's Triangle.cpp ├── 7. DP - Longest Common Subsequence.cpp ├── 8. DP - Edit Distance.cpp ├── 9. DP - Longest Increasing Subsequence.cpp ├── DP - Longest Palindromic Subsequence.cpp ├── DP - Longest Palindromic Substring.cpp ├── DP - Palindromic Substrings.cpp └── LIS - Russian Doll Envelopes.cpp ├── DSU ├── 1. DSU - Journey to the Moon.cpp ├── 18. DSU - CLFLARR - COLORFUL ARRAY.cpp ├── 19. Redundant Connection.cpp ├── 2. DSU - Couples Holding Hands.cpp ├── 20. Redundant Connection II.cpp ├── 3. Union-Find.cpp ├── 4. Disjoint set (Union-Find).cpp ├── 5. Detect Cycle using DSU.cpp ├── Accounts Merge.cpp ├── Couples Holding Hands.cpp ├── Lexicographically smallest equivalent string.cpp ├── Possible Bipartition.cpp └── Validate Binary Tree Nodes.cpp ├── Dijkstra └── 1. Dijkstra.cpp ├── Graph ├── 10. Clone Graph.cpp ├── 11. DFS - Detect cycle in an undirected graph.cpp ├── 12. BFS - Detect cycle in an undirected graph.cpp ├── 13. cycleInDirectedGraph.cpp ├── 14. DFS - Detect directed cycle - Course Schedule.cpp ├── 15. BFS - Detect directed cycle - Course Schedule.cpp ├── 7. BFS - Word Ladder.cpp ├── 8. Number of Provinces.cpp ├── 9. Flood Fill.cpp ├── Easy │ ├── 1. DFS - Evaluate Boolean Binary Tree.cpp │ └── 2. DFS Matrix -Island Perimeter.cpp ├── Hard │ ├── 1. BFS - Word Ladder.cpp │ ├── 2. PriorityQueue - Course Schedule III.cpp │ ├── 3. BFS PriorityQueue - Swim in Rising Water.cpp │ ├── 3. DFS - Reconstruct Itinerary.cpp │ ├── 4. Multisource BFS - Shortest Path Visiting All Nodes.cpp │ ├── DFS - Capture Regions on Board.cpp │ ├── Sum of Distances in Tree.cpp │ └── Word Search Board.cpp ├── Leetcode graph theory series │ ├── As Far from Land as Possible.cpp │ ├── BFS + DFS Shortest Bridge.cpp │ ├── Count Sub Islands.cpp │ ├── Flood Fill.cpp │ ├── Is Graph Bipartite.cpp │ ├── Maximal Network Rank.cpp │ ├── Minimum Genetic Mutation.cpp │ ├── Nearest Exit from Entrance in Maze.cpp │ ├── Number of Closed Islands.cpp │ ├── Number of Enclaves.cpp │ ├── Number of Islands.cpp │ ├── Open the Lock.cpp │ ├── Pacific Atlantic Water Flow.cpp │ └── Word Ladder.cpp └── Medium │ ├── 1. Adjacency List - Minimum Number of Vertices to Reach All Nodes.cpp │ ├── 10. TopologicalSort - Course Schedule.cpp │ ├── 11. Course Schedule II.cpp │ ├── 12. DSU - Longest Consecutive Sequence.cpp │ ├── 13. DFS in Grid - Surrounded Regions.cpp │ ├── 14. Map - Clone Graph.cpp │ ├── 2. Adjacency List - Maximum Total Importance of Roads.cpp │ ├── 3. Reverse BFS - Minimum Height Trees.cpp │ ├── 4. UnionFind.cpp │ ├── 5. BFS - Amount of Time for Binary Tree to Be Infected.cpp │ ├── 5. DSU - Redundant Connection.cpp │ ├── 6. DFS - Number of Enclaves.cpp │ ├── 7. DFS - Number of Closed Islands.cpp │ ├── 8. Astronaut Pairs.cpp │ └── 9. DFS - Validate Binary Search Tree.cpp ├── Hashing ├── 1. Hashing - Valid Sudoku.cpp ├── 16. Longest Consecutive Sequence.cpp └── Set of Sets - Count Words Obtained After Adding a Letter.cpp ├── Heap or Priority Queue └── Find Median from Data Stream.cpp ├── Linked List ├── 1. LinkedList - Merge k Sorted Lists.cpp └── 2. Maximum Twin Sum of a Linked List.cpp ├── Minimum Spanning Tree └── Kruskal's - Min Cost to Connect All Points.cpp ├── Mixed ├── 1. Find Original Array From Doubled Array.cpp ├── 10. Count Servers that Communicate.cpp ├── 11. Number of Operations to Make Network Connected.cpp ├── 12. Get minimum element from stack.cpp ├── 13. Subrectangle Queries.cpp ├── 14. Max Increase to Keep City Skyline.cpp ├── 15. Longest Subarray With Maximum Bitwise AND.cpp ├── 2. Number of Ways to Arrive at Destination.cpp ├── 6. Binary Decimal Conversion.cpp ├── 7. Max Area of Island.cpp ├── 8. Min Cost to Connect All Points.cpp ├── 9. Longest Consecutive Sequence.cpp ├── Easy │ ├── 1. Map - Decode the Message.cpp │ ├── 2. Minimum Hours of Training to Win a Competition.cpp │ ├── 3. Average of Levels in Binary Tree.cpp │ └── 4. Construct String from Binary Tree.cpp ├── Hard │ ├── 4. DFS + DP - Number of Increasing Paths in a Grid.cpp │ └── 5. Vertical Order Traversal of a Binary Tree.cpp └── Medium │ ├── 10. Count Good Nodes in Binary Tree.cpp │ ├── 2. Matrix Traversal - Spiral Matrix IV.cpp │ ├── 3. DP - Number of People Aware of a Secret.cpp │ ├── 4. PriorityQueue - Largest Palindromic Number.cpp │ ├── 6. Sort the Matrix Diagonally.cpp │ ├── 7. House Robber II.cpp │ ├── 8. PrefixSum - Shifting Letters II.cpp │ ├── 9. Numbers With Same Consecutive Differences.cpp │ ├── Array - Product of Array Except Self.cpp │ ├── Array - Spiral Matrix.cpp │ ├── Minimum Operations to Make Array Equal II.cpp │ └── Stack & string - Evaluate Reverse Polish Notation.cpp ├── Recursion ├── 1. Recursion - Reverse String.cpp ├── 10. Recursion - Find the Winner of the Circular Game.cpp ├── 11. Recursion - Maximum Length of a Concatenated String with Unique Characters.cpp ├── 12. Recursion - Partition to K Equal Sum Subsets.cpp ├── 13. Recursion - Flood Fill.cpp ├── 14. Recursion - Rat In A Maze.cpp ├── 2. Recursion - Reverse Linked List.cpp ├── 3. Recursion - Fibonacci Number.cpp ├── 4. Recursion - Merge Two Sorted Lists.cpp ├── 5. Recursion - Palindrome Linked List.cpp ├── 6. Recursion - Power of Two.cpp ├── 7. Recursion - Power of Four.cpp ├── 8. Recursion - Remove Linked List Elements.cpp └── 9. Recursion - Power of Three.cpp ├── Sliding Window └── Sliding Window Maximum.cpp ├── Topological Sort ├── 16. Topological Sort - Loud and Rich.cpp ├── Alien Dictionary.cpp ├── Course Schedule II.cpp ├── Course Schedule.cpp ├── Minimum Height Trees.cpp └── White-Gray-Black - Find Eventual Safe States.cpp ├── Tree ├── 1. Maximum Depth of Binary Tree.cpp ├── 10. N-ary Tree Preorder Traversal.cpp ├── 11. Binary Tree Level Order Traversal.cpp ├── 11. Binary Tree Pruning.cpp ├── 12. N-ary Tree Level Order Traversal.cpp ├── 13. Vertical Order Traversal of a Binary Tree.cpp ├── 14. Diagonal Traversal of Binary Tree.cpp ├── 2. Minimum Depth of Binary Tree.cpp ├── 3. Balanced Binary Tree.cpp ├── 4. Maximum Depth of N-ary Tree.cpp ├── 5. Same Tree.cpp ├── 6. Diameter of Binary Tree.cpp ├── 7. Find a Corresponding Node of a Binary Tree in a Clone of That Tree.cpp ├── 8. Binary Tree Preorder Traversal.cpp └── 9. N-ary Tree Postorder Traversal.cpp ├── Trie ├── 6. Trie.cpp ├── Phone directory.cpp ├── Search Suggestions System.cpp └── Word Boggle.cpp └── Two Pointer ├── 3. Two Pointer - Minimize Maximum Pair Sum in Array.cpp ├── 4. Two Pointer - Partition Labels.cpp ├── 5. Two Pointer - Jump Game.cpp └── Next Greater Element III.cpp /Binary Search/Binary Search - STL.cpp: -------------------------------------------------------------------------------- 1 | // Binary Search - C++ STL 2 | bool binarySearchSTL(vector arr, int valueToSearch) { 3 | auto startAddress = arr.begin(); 4 | auto endAddress = arr.end(); 5 | 6 | bool ans = binary_search(startAddress, endAddress, valueToSearch); 7 | return ans; 8 | 9 | /* 10 | lower_bound -> n iterator to the lower bound of val in the range 11 | returns an iterator to the lower bound of key in the range 12 | */ 13 | /* 14 | upper_bound -> the element just greater than valueToSearch 15 | returns an iterator to the upper bound of val in the range 16 | */ 17 | } -------------------------------------------------------------------------------- /Binary Search/Binary Search Template.cpp: -------------------------------------------------------------------------------- 1 | // Binary Search - iterative 2 | int binarySearchIterative(vector arr, int valueToSearch) { 3 | int low = 0, high = arr.size()-1; 4 | while(low<=high){ 5 | int mid = (low+high)/2; 6 | if(valueToSearch == arr[mid]) 7 | return mid; 8 | else if(valueToSearch > arr[mid]) // valueToSearch is on the right 9 | low = mid + 1; 10 | else // valueToSearch is on the left 11 | high = mid - 1; 12 | } 13 | return -1; 14 | } 15 | 16 | // Binary Search - recursive 17 | int binarySearchRecursive(vector arr, int valueToSearch, int low, int high) { 18 | if(low>high) 19 | return -1; 20 | int mid = low + (high-low)/2; 21 | if(valueToSearch == arr[mid]) 22 | return mid; 23 | else if(valueToSearch > arr[mid]) // valueToSearch is on the right 24 | return binarySearchRecursive(arr, valueToSearch, mid+1, high); 25 | else // valueToSearch is on the left 26 | return binarySearchRecursive(arr, valueToSearch, low, mid-1); 27 | } 28 | int binarySearch(vector arr, int valueToSearch) { 29 | return binarySearchRecursive(arr, valueToSearch, 0, arr.size()-1); 30 | } -------------------------------------------------------------------------------- /Binary Search/Magnetic Force Between Two Balls.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | int calculateMinDist(vector& position, int dist){ 3 | int ans=1; 4 | int prevPos=position[0]; 5 | for(int i=1;i=(prevPos+dist)){ 7 | ans++; 8 | prevPos=position[i]; 9 | } 10 | } 11 | return ans; 12 | } 13 | public: 14 | int maxDistance(vector& position, int m) { 15 | int n=position.size(); 16 | sort(position.begin(), position.end()); 17 | int s=1; // minimum magnetic force 18 | int e=position[n-1]-position[0]; 19 | int ans=-1; 20 | while(s<=e){ 21 | int mid=(e-s)/2+s; 22 | int baskets=calculateMinDist(position, mid); 23 | cout<=m){ 25 | ans=max(mid, ans); 26 | s=mid+1; 27 | } 28 | else{ 29 | e=mid-1; 30 | } 31 | } 32 | return ans; 33 | } 34 | }; -------------------------------------------------------------------------------- /Bit Manipulation/Reverse Bits.cpp: -------------------------------------------------------------------------------- 1 | // https://www.interviewbit.com/problems/reverse-bits 2 | 3 | unsigned int Solution::reverse(unsigned int A) { 4 | // Do not write main() function. 5 | // Do not read input, instead use the arguments to the function. 6 | // Do not print the output, instead return values as specified 7 | // Still have a doubt. Checkout www.interviewbit.com/pages/sample_codes/ for more details 8 | unsigned int B=0; 9 | int k=0; 10 | while(k++<32){ 11 | B=B<<1; 12 | // cout<>1; 15 | } 16 | return B; 17 | } 18 | 19 | /* 20 | Time, Space: O(1) 21 | */ 22 | -------------------------------------------------------------------------------- /Bit Manipulation/Single Number II.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/single-number-ii/ 2 | 3 | class Solution { 4 | public: 5 | int singleNumber(vector& nums) { 6 | int x = 0; 7 | for(auto a:nums) x^=a; 8 | vector v(32); 9 | for(auto a:nums) { 10 | int y = x^a; 11 | for(int i=0;i<32;i++) { 12 | if((y>>i)&1)v[i]++; 13 | } 14 | } 15 | int ans=0; 16 | for(int i=0;i<32;i++) { 17 | // cout<& nums) { 6 | int a=0; 7 | for(int i:nums) 8 | a=a^i; 9 | return a; 10 | } 11 | }; -------------------------------------------------------------------------------- /DP/1. DP - Climbing Stairs.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/climbing-stairs/ 2 | 3 | // top-down 4 | class Solution { 5 | int dp[46]; 6 | public: 7 | int climbStairs(int n) { 8 | if(dp[n]!=0) 9 | return dp[n]; 10 | if(n==1) 11 | return dp[1]=1; 12 | if(n==2) 13 | return dp[2]=2; 14 | return dp[n]=climbStairs(n-1)+climbStairs(n-2); 15 | } 16 | }; 17 | 18 | // bottom-up 19 | class Solution { 20 | public: 21 | int climbStairs(int n) { 22 | vector dp(46); 23 | dp[0]=1; 24 | dp[1]=1; 25 | for(int i=2; i<=n; i++) { 26 | dp[i]=dp[i-1]+dp[i-2]; 27 | } 28 | return dp[n]; 29 | } 30 | }; -------------------------------------------------------------------------------- /DP/10. DP - Stone Game.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/stone-game/ 2 | 3 | class Solution { 4 | int memo[501][501]; 5 | int solve(vector &piles, int s, int e){ 6 | if(s>e) 7 | return 0; 8 | if(memo[s][e]!=-1) 9 | return memo[s][e]; 10 | return memo[s][e]=max(piles[s]-solve(piles, s+1, e), piles[e]-solve(piles, s, e-1)); 11 | } 12 | public: 13 | bool stoneGame(vector& piles) { 14 | int n= piles.size(); 15 | memset(memo, -1, sizeof memo); 16 | return solve(piles, 0, n-1)>0; 17 | } 18 | }; -------------------------------------------------------------------------------- /DP/11. DP - Egg Drop.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/egg-drop-with-2-eggs-and-n-floors/ 2 | 3 | // recursive DP - gives TLE 4 | class Solution { 5 | int help(int e, int f, vector> &dp) { 6 | if(dp[e][f]!=-1) 7 | return dp[e][f]; 8 | // for(int i=0;i<10;i++){ 9 | // for(int j=0;j<10;j++){ 10 | // cout<> dp(101, vector (10001, -1)); 29 | return help(e, f, dp); 30 | } 31 | }; 32 | 33 | // 2D DP k*n giving TLE 34 | class Solution { 35 | public: 36 | int superEggDrop(int k=2, int n) { 37 | int dp[k+1][n+1]; 38 | memset(dp, 0, sizeof dp); 39 | for(int j=1;j<=n;j++){ 40 | dp[1][j]=j; 41 | } 42 | for(int i=2;i<=k;i++){ // eggs 43 | for(int j=1;j<=n;j++){ // floors 44 | dp[i][j]=1; 45 | // starting with diff floors 46 | int m=INT_MAX; 47 | for(int a=1;a<=j;a++){ 48 | m=min(m, max(dp[i-1][a-1], dp[i][j-a])); // broken, unbroken 49 | } 50 | dp[i][j]+=m; 51 | } 52 | } 53 | return dp[k][n]; 54 | } 55 | }; -------------------------------------------------------------------------------- /DP/12. DP - Maximal Rectangle.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/maximal-rectangle/ 2 | 3 | class Solution { 4 | int MAH(vector &arr){ 5 | stack st; 6 | int n=arr.size(); 7 | vector nsleft(n), nsright(n); 8 | // populating next smallest to the left 9 | for(int i=0;iarr[st.top()]){ 15 | nsleft[i]=st.top(); 16 | st.push(i); 17 | } 18 | else{ 19 | while(!st.empty() && arr[st.top()]>=arr[i]){ 20 | st.pop(); 21 | } 22 | if(st.empty()){ 23 | nsleft[i]=-1; 24 | st.push(i); 25 | } 26 | else{ 27 | nsleft[i]=st.top(); 28 | st.push(i); 29 | } 30 | } 31 | } 32 | while(!st.empty()) 33 | st.pop(); 34 | 35 | // populating next smallest to the right 36 | for(int i=n-1;i>=0;i--){ 37 | if(st.empty()){ 38 | st.push(i); 39 | nsright[i]=n; 40 | } 41 | else if(arr[i]>arr[st.top()]){ 42 | nsright[i]=st.top(); 43 | st.push(i); 44 | } 45 | else{ 46 | while(!st.empty() && arr[st.top()]>=arr[i]){ 47 | st.pop(); 48 | } 49 | if(st.empty()){ 50 | nsright[i]=n; 51 | st.push(i); 52 | } 53 | else{ 54 | nsright[i]=st.top(); 55 | st.push(i); 56 | } 57 | } 58 | } 59 | while(!st.empty()) 60 | st.pop(); 61 | int mah=0; 62 | for(int i=0;i>& matrix) { 71 | // step-1: dp table 72 | int r=matrix.size(), c=matrix[0].size(); 73 | vector> dp(r, vector (c, 0)); 74 | for(int i=0;i& arr) { 6 | // Your code here 7 | int maxSum=INT_MIN, sum=0; 8 | for(int i=0;i& coins, int amount) { 6 | int Max = amount + 1; 7 | vector dp(amount + 1, Max); 8 | dp[0] = 0; 9 | for (int i = 1; i <= amount; i++) { 10 | for (int j = 0; j < coins.size(); j++) { 11 | if (coins[j] <= i) { 12 | dp[i] = min(dp[i], dp[i - coins[j]] + 1); 13 | } 14 | } 15 | } 16 | return dp[amount] > amount ? -1 : dp[amount]; 17 | } 18 | }; -------------------------------------------------------------------------------- /DP/3. DP - Counting Bits.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/counting-bits/ 2 | 3 | class Solution { 4 | public: 5 | vector countBits(int n) { 6 | // last digit in the binary representation of i = i&1 7 | // no. of ones in i = no. of ones in i/2 + last digit==1?1:0 8 | vector ans(n+1, 0); 9 | for(int i=1;i<=n;i++){ 10 | ans[i]=ans[i>>1]+(i&1); 11 | } 12 | return ans; 13 | } 14 | }; -------------------------------------------------------------------------------- /DP/4. DP - Divisor Game.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/divisor-game/ 2 | 3 | class Solution { 4 | public: 5 | bool divisorGame(int n) { 6 | // notice the pattern of who wins 7 | return n%2==0; 8 | } 9 | }; -------------------------------------------------------------------------------- /DP/5. DP - Jump Game II.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/jump-game-ii/ 2 | 3 | class Solution { 4 | public: 5 | int jump(vector& nums) { 6 | int n=nums.size(); 7 | vector dp(n+1, INT_MAX); 8 | int maxi=-1; 9 | if(nums[0]) 10 | dp[0]=0, maxi=0; 11 | for(int i=0;i& nums, int target){ 7 | if(i==nums.size()){ 8 | if(target==0) 9 | return 1; 10 | return 0; 11 | } 12 | if(dp[i][target+1000]!=-1) 13 | return dp[i][target+1000]; 14 | // add 15 | if(nums[i]<=target) 16 | return dp[i][target+1000] = help(i+1, nums, target-nums[i])+help(i+1, nums, target); 17 | 18 | // subtract 19 | return dp[i][target+1000] = help(i+1, nums, target); 20 | 21 | } 22 | public: 23 | int findTargetSumWays(vector& nums, int target) { 24 | memset(dp, -1, sizeof dp); 25 | int sum=accumulate(nums.begin(), nums.end(), 0); 26 | if(target>sum || (target+sum)%2) 27 | return 0; 28 | int t=(sum+target)/2; 29 | int ans=help(0, nums, t); 30 | return ans; 31 | } 32 | }; 33 | 34 | // Recursion 35 | class Solution { 36 | vector> dp; 37 | int help(int i, int &ans, vector& nums, int target){ 38 | if(i==nums.size()){ 39 | if(target==0) 40 | return 1; 41 | return 0; 42 | } 43 | // add 44 | help(i+1, ans, nums, target-nums[i]); 45 | // subtract 46 | help(i+1, ans, nums, target+nums[i]); 47 | 48 | } 49 | public: 50 | int findTargetSumWays(vector& nums, int target) { 51 | int ans=0; 52 | dp.resize(nums.size(), vector> ({-1, -1})); 53 | help(0, ans, nums, target); 54 | return ans; 55 | } 56 | }; -------------------------------------------------------------------------------- /DP/6. DP - Pascal's Triangle.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/pascals-triangle/ 2 | 3 | class Solution { 4 | public: 5 | vector> generate(int &numRows) { 6 | vector> dp; 7 | dp.resize(numRows); 8 | dp[0]={1}; 9 | for(int i=1;i& nums) { 6 | int n=nums.size(); 7 | if(n<1) return 0; 8 | int ans=1; 9 | vector dp(n, 1); 10 | for(int i=1;i> dp(n, vector (n, 1)); 10 | 11 | for(int len=2;len<=n;len++){ 12 | for(int i=0;i<=n-len;i++){ 13 | int j=i+len-1; 14 | if(s[i]==s[j]){ 15 | if(len==2){ 16 | dp[i][j]=2; 17 | } 18 | else if(i0){ 19 | dp[i][j]=dp[i+1][j-1]+2; 20 | } 21 | ans=max(ans, dp[i][j]); 22 | } 23 | else{ 24 | dp[i][j]=max(dp[i+1][j], dp[i][j-1]); 25 | } 26 | } 27 | } 28 | 29 | return ans; 30 | } 31 | }; 32 | 33 | /* 34 | Time, Space : O(n*m) 35 | */ -------------------------------------------------------------------------------- /DP/DP - Longest Palindromic Substring.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/longest-palindromic-substring/ 2 | 3 | // length wise matrix taversal in DP 4 | // substr in C++ takes (pos, len) if 2 integer args are passed 5 | // https://www.geeksforgeeks.org/substring-in-cpp/ 6 | 7 | class Solution { 8 | public: 9 | string longestPalindrome(string &s) { 10 | // 2D DP 11 | int n=s.length(); 12 | string ans; 13 | ans.push_back(s[0]); 14 | vector> dp(n, vector (n, 0)); 15 | for(int i=0;i0){ 26 | dp[i][j]=dp[i+1][j-1]; 27 | } 28 | 29 | if(dp[i][j] && ans.size()> dp(n, vector (n, 0)); 10 | 11 | for(int len=1;len<=n;len++){ 12 | for(int i=0;i<=n-len;i++){ 13 | int j=i+len-1; 14 | if(s[i]==s[j]){ 15 | if(len<=2){ 16 | dp[i][j]=1; 17 | } 18 | else if(i0){ 19 | dp[i][j]=dp[i+1][j-1]; 20 | } 21 | 22 | if(dp[i][j]) 23 | ans++; 24 | } 25 | } 26 | } 27 | 28 | return ans; 29 | } 30 | }; 31 | 32 | /* 33 | Time, Space : O(n*m) 34 | */ -------------------------------------------------------------------------------- /DP/LIS - Russian Doll Envelopes.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/russian-doll-envelopes/ 2 | // LIS in (nlogn) 3 | 4 | class Solution { 5 | static bool cmp(const vector &a, const vector &b){ 6 | if(a[0]==b[0]) 7 | return a[1]>b[1]; 8 | return a[0]>& env) { 12 | int n=env.size(); 13 | if(n==0) 14 | return 0; 15 | sort(env.begin(), env.end(), cmp); 16 | vector lis; 17 | for(int i=0;i=lis.size()) lis.push_back(env[i][1]); 20 | else lis[it]=env[i][1]; 21 | } 22 | return lis.size(); 23 | } 24 | }; 25 | 26 | /* 27 | eg1. 28 | (2,1) (2,6) (3,4) -> 1,4 29 | (2,6) (2,1) (3,4) -> 1,4 30 | 31 | eg2. 32 | [[4,5],[4,6],[6,7],[2,3],[1,1]] 33 | 34 | [[1,1],[2,3],[4,5],[4,6],[6,7]] [1,3,5,6,7] 35 | [[1,1],[2,3],[4,6],[4,5],[6,7]] [1,3,6,7] 36 | */ 37 | -------------------------------------------------------------------------------- /DSU/18. DSU - CLFLARR - COLORFUL ARRAY.cpp: -------------------------------------------------------------------------------- 1 | // https://www.spoj.com/problems/CLFLARR/ 2 | 3 | #include 4 | using namespace std; 5 | #define ll long long 6 | 7 | class DSU{ 8 | public: 9 | vector par; 10 | DSU(ll n){ 11 | par.resize(n); 12 | for(ll i=0;i>n>>q; 31 | vector l(n), r(n), c(n), ans(n); 32 | for(ll i=0;i>l[i]>>r[i]>>c[i]; 34 | } 35 | DSU dsu(300000); 36 | for(ll i=q-1; i>=0; i--){ 37 | ll left=dsu.find(l[i]); 38 | while(left<=r[i]){ 39 | ans[left]=c[i]; 40 | dsu.union_(left, left+1); 41 | left=dsu.find(left); 42 | } 43 | } 44 | for(ll i=1;i<=n;i++){ 45 | cout< par; 8 | DSU(ll n){ 9 | par.resize(n); 10 | for(ll i=0;i findRedundantConnection(vector>& edges) { 29 | int n=edges.size(); 30 | vector ans(2,-1); 31 | DSU dsu(1001); 32 | for(int i=0; i par; 17 | DSU(int &n){ 18 | par.resize(n, 0); 19 | } 20 | int Find(int a){ 21 | if(a==par[a]) 22 | return a; 23 | // path compression 24 | return par[a]=Find(par[a]); 25 | } 26 | bool Union(int a, int b){ 27 | int par_a=Find(a); 28 | int par_b=Find(b); 29 | if(par_a==par_b) 30 | return false; 31 | par[par_b]=par_a; 32 | return true; 33 | } 34 | }; 35 | 36 | class Solution { 37 | public: 38 | int minSwapsCouples(vector& row) { 39 | int n=row.size(); 40 | DSU dsu(n); 41 | 42 | for(int i=0;i par; 8 | DSU(ll n){ 9 | par.resize(n); 10 | for(ll i=0;i findRedundantDirectedConnection(vector>& edges) { 29 | int n=edges.size(); 30 | vector inDegEdge(1001, -1); 31 | DSU dsu(1001); 32 | 33 | // noting down the last edge in edges having more than 1 parent 34 | int d1=-1, d2=-1; 35 | for(int i=0; i b dominates 21 | rank1[par_b]++; 22 | par[par_a]=par_b; 23 | } 24 | else{ 25 | // a dominates 26 | rank1[par_a]++; 27 | par[par_b]=par_a; 28 | } 29 | } 30 | } 31 | 32 | //Function to check whether 2 nodes are connected or not. 33 | bool isConnected(int x,int y, int par[], int rank1[]) 34 | { 35 | //code here 36 | return find(x, par)==find(y, par); 37 | } 38 | }; 39 | 40 | /* 41 | Time Complexity: O(n) 42 | Space Complexity: O(n) 43 | */ -------------------------------------------------------------------------------- /DSU/4. Disjoint set (Union-Find).cpp: -------------------------------------------------------------------------------- 1 | // https://practice.geeksforgeeks.org/problems/disjoint-set-union-find/1?page=1&category[]=union-find&category[]=Disjoint%20Set&sortBy=submissions 2 | 3 | /*Complete the functions below*/ 4 | int find(int par[],int a) 5 | { 6 | //add code here 7 | if(a==par[a]) 8 | return a; 9 | return par[a]=find(par, par[a]); 10 | } 11 | void unionSet(int par[],int a,int b) 12 | { 13 | //add code here. 14 | int par_a=find(par, par[a]); 15 | int par_b=find(par, par[b]); 16 | if(par_a!=par_b){ 17 | par[par_a]=par_b; 18 | } 19 | } 20 | 21 | /* 22 | Time Complexity: 23 | Space Complexity: 24 | */ -------------------------------------------------------------------------------- /DSU/5. Detect Cycle using DSU.cpp: -------------------------------------------------------------------------------- 1 | // https://practice.geeksforgeeks.org/problems/detect-cycle-using-dsu/1?page=1&status[]=unsolved&category[]=union-find&category[]=Disjoint%20Set&sortBy=submissions 2 | 3 | class Solution 4 | { 5 | int find(int a, vector &par){ 6 | // finding parent 7 | if(a==par[a]){ 8 | return a; 9 | } 10 | return par[a]=find(par[a], par); 11 | } 12 | void union_(int a, int b, vector &par){ 13 | par[a]=b; 14 | } 15 | public: 16 | //Function to detect cycle using DSU in an undirected graph. 17 | int detectCycle(int V, vectoradj[]) 18 | { 19 | // Code here 20 | vector par(V); 21 | for(int i=0;i par; 7 | DSU(int n){ 8 | par.resize(n); 9 | for(int i=0;i> accountsMerge(vector>& accounts) { 30 | int n=accounts.size(); 31 | unordered_map ids; 32 | DSU dsu(n); 33 | for(int i=0;i mergedMail[n]; 44 | for(auto &i: ids){ 45 | string mail=i.first; 46 | int id=dsu.find(i.second); 47 | mergedMail[id].insert(mail); 48 | } 49 | vector> ans; 50 | for(int i=0;i v; 52 | v.push_back(accounts[i][0]); 53 | set mails=mergedMail[i]; 54 | for(auto &m: mails){ 55 | v.push_back(m); 56 | } 57 | if(v.size()>1) 58 | ans.push_back(v); 59 | } 60 | return ans; 61 | } 62 | }; 63 | 64 | /* 65 | n=no. of accounts 66 | k=mail length of mail 67 | Time: O(nklog(nk)) 68 | Space: O(nk) 69 | */ -------------------------------------------------------------------------------- /DSU/Couples Holding Hands.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/couples-holding-hands/ 2 | 3 | class Solution { 4 | class DSU { 5 | public: 6 | vector par; 7 | DSU(int n, vector row){ 8 | par.resize(n,0); 9 | for(int i=0;i& row) { 31 | int n=row.size(), ans=0; 32 | DSU dsu(n, row); 33 | for(int i=0;i "; 35 | if(dsu.union_(i, i+1)) 36 | ans++; 37 | } 38 | return ans; 39 | } 40 | }; 41 | 42 | /* 43 | Time: O(V+E) 44 | Space: O(V+E) 45 | */ -------------------------------------------------------------------------------- /DSU/Lexicographically smallest equivalent string.cpp: -------------------------------------------------------------------------------- 1 | // https://www.codingninjas.com/codestudio/problems/smallest-equivalent-string_1381859 2 | 3 | #include 4 | class DSU{ 5 | public: 6 | vector par; 7 | DSU(int n){ 8 | par.resize(n); 9 | for(int i=0;i par; 9 | DSU(int n){ 10 | par.resize(n); 11 | for(int i=0;i>& dislikes) { 26 | vector> graph(n); 27 | for(auto &d: dislikes){ 28 | graph[d[0]-1].push_back(d[1]-1); 29 | graph[d[1]-1].push_back(d[0]-1); 30 | } 31 | DSU dsu(n); 32 | for(int i=0;i par; 8 | DSU(int n) { 9 | par.resize(n, 0); 10 | for(int i=0;i& leftChild, vector& rightChild) { 24 | DSU dsu(n); 25 | for(int i=0;i"; 27 | int par=dsu.find(i); 28 | // cout< inDeg(n, 0); 47 | for(int i=0;i1) 61 | return false; 62 | } 63 | return true; 64 | } 65 | }; 66 | 67 | /* 68 | Time: O(n) 69 | Space: O(n) 70 | */ -------------------------------------------------------------------------------- /Dijkstra/1. Dijkstra.cpp: -------------------------------------------------------------------------------- 1 | // Dijkstra 2 | 3 | int dijkstra(int src, int dest) { 4 | vector dist(V, INT_MAX); // V=no. of vertices 5 | set> s; 6 | 7 | dist[src]=0; 8 | s.insert({0, src}); 9 | 10 | while(!s.empty()){ 11 | auto it=s.begin(); 12 | int node=it->second; 13 | int nodeDist=it->first; 14 | s.erase(it); 15 | 16 | for(auto &nbr: graph[node]){ 17 | int nbrNode=nbr->second; 18 | int nbrDist=nbr->first; 19 | 20 | if(nodeDist+nbrDist neighbors; 9 | Node() { 10 | val = 0; 11 | neighbors = vector(); 12 | } 13 | Node(int _val) { 14 | val = _val; 15 | neighbors = vector(); 16 | } 17 | Node(int _val, vector _neighbors) { 18 | val = _val; 19 | neighbors = _neighbors; 20 | } 21 | }; 22 | */ 23 | 24 | class Solution { 25 | // original and clone map 26 | unordered_map clone; 27 | public: 28 | Node* cloneGraph(Node* node) { 29 | if(!node) 30 | return node; 31 | if(clone.find(node)==clone.end()){ 32 | // using this check, we avoid cloning node again 33 | // eg. 1->2; 2->1 => if 1 is created and then 2 gets created 34 | // 1 won't get created again through 2 (nbr) 35 | clone[node]=new Node(node->val); 36 | for(Node* nbr: node->neighbors){ 37 | clone[node]->neighbors.push_back(cloneGraph(nbr)); 38 | } 39 | } 40 | return clone[node]; 41 | } 42 | }; 43 | 44 | /* 45 | Time Complexity: O(n) 46 | Space Complexity: O(n) 47 | */ -------------------------------------------------------------------------------- /Graph/11. DFS - Detect cycle in an undirected graph.cpp: -------------------------------------------------------------------------------- 1 | // https://practice.geeksforgeeks.org/problems/detect-cycle-in-an-undirected-graph/1 2 | 3 | class Solution { 4 | bool dfs(int i, vector &vis, int par, vector adj[]) { 5 | vis[i]=1; 6 | for(int &nbr: adj[i]){ 7 | if(nbr!=par && (vis[nbr] || dfs(nbr, vis, i, adj))){ 8 | return true; 9 | } 10 | } 11 | return false; 12 | } 13 | public: 14 | // Function to detect cycle in an undirected graph. 15 | bool isCycle(int n, vector adj[]) { 16 | // Code here 17 | // using dfs 18 | vector vis(n, false); 19 | for(int i=0;i adj[]) { 7 | // Code here 8 | // using bfs 9 | vector vis(n, false); 10 | for(int i=0;i> q; 13 | q.push({i, -1}); 14 | while(!q.empty()){ 15 | auto f=q.front(); 16 | q.pop(); 17 | vis[f.first]=1; 18 | for(int &nbr: adj[f.first]){ 19 | if(nbr!=f.second && vis[nbr]) 20 | return true; 21 | if(!vis[nbr]) 22 | q.push({nbr, f.first}); 23 | } 24 | } 25 | } 26 | } 27 | return false; 28 | } 29 | }; 30 | 31 | /* 32 | Time Complexity: O(n) 33 | Space Complexity: O(n) 34 | */ -------------------------------------------------------------------------------- /Graph/13. cycleInDirectedGraph.cpp: -------------------------------------------------------------------------------- 1 | class cycleInDirectedGraph{ 2 | bool checkCycle(int i, int currVis[], vector &adj[]), int vis[]) { 3 | vis[i]=1; 4 | currVis[i]=1; 5 | for(auto &nbr: adj[i]){ 6 | if(!vis[nbr]){ 7 | if(checkCycle(nbr, currVis, adj, vis) 8 | return true; 9 | if(currVis[i]) 10 | retun true; 11 | } 12 | return false; 13 | } 14 | public: 15 | bool isCyclic(int n, vector &adj[]) { 16 | int vis[n]; 17 | for(int i=0;i &currVis, vector &vis, unordered_map> &graph) { 7 | vis[i]=1; 8 | currVis[i]=1; 9 | for(int &nbr: graph[i]){ 10 | if(!vis[nbr]){ 11 | if(dfs(nbr, currVis, vis, graph)) 12 | return true; 13 | } 14 | else if(currVis[nbr]){ 15 | return true; 16 | } 17 | } 18 | currVis[i]=false; 19 | return false; 20 | } 21 | 22 | public: 23 | bool canFinish(int numCourses, vector>& prerequisite) { 24 | // create a graph -> adj list 25 | unordered_map> graph; 26 | for(int i=0;i vis(numCourses, false); 32 | for(int i=0;i currVis(numCourses, false); 35 | // cout<>& prerequisite) { 8 | int np=prerequisite.size(); 9 | // create a graph -> adj list 10 | unordered_map> graph; 11 | vector inDeg(n, 0); 12 | for(int i=0;i vis(n, false); 19 | // store all the courses with no dependency in queue 20 | queue q; 21 | for(int i=0;i cog 6 | - for the beginWord, it doesn't matter if it is in the wordList or not 7 | - for the endWord, it does - otherwise how will we even reach to endWord? 8 | -1- thus, the first thing that we need to check is whether the endWord is present in the wordList or not 9 | - as the problem is about finding the minimum length path 10 | for the transition from beginWord to endWord 11 | -2- we will use BFS, thus a Queue data structure 12 | - initially, we will push the beginWord into the queue 13 | - it is important to process all the words at a level together 14 | - because they should all be treated equally 15 | -3- for that, we will pop the queue elements level by level 16 | - for each word, we need to find it's neighbour 17 | -4- we find the neighbour by replacing each char with all 26 other aphabets 18 | - and if that newly found word is present and unvisited, we push it into the queue 19 | -5- we use a set of visited strings to avoid loops and level to keep track of min length 20 | - compare if the words match 21 | */ 22 | 23 | class Solution { 24 | public: 25 | int ladderLength(string beginWord, string endWord, vector& wordList) { 26 | // step 1 27 | set words; 28 | for(auto &s: wordList) 29 | words.insert(s); 30 | if(words.find(endWord)==words.end()) 31 | return 0; 32 | 33 | // step 2 34 | queue q; 35 | q.push(beginWord); 36 | 37 | int lvl=1; 38 | set vis; 39 | vis.insert(beginWord); 40 | 41 | while(!q.empty()){ 42 | // step 3 43 | int s=q.size(); 44 | while(s--){ 45 | string t=q.front(); 46 | q.pop(); 47 | string temp; 48 | for(int i=0;i &vis, map> &graph) { 5 | vis[i]=1; 6 | for(auto &nbr: graph[i]){ 7 | if(!vis[nbr]){ 8 | dfs(nbr, vis, graph); 9 | } 10 | } 11 | } 12 | public: 13 | int findCircleNum(vector>& isConnected) { 14 | int n=isConnected.size(); 15 | map> graph; 16 | 17 | // adj matrix to adj list 18 | for(int i=0;i vis(n, 0); 28 | int cnt=0; 29 | 30 | for(int i=0;i dx={-1, 0, 1, 0}, dy={0, 1, 0, -1}; 5 | void floodfill(int sr, int sc, int color, int parClr, vector>& image){ 6 | // cout<=0 && newr=0 && newc> floodFill(vector>& image, int sr, int sc, int color) { 22 | int n=image.size(); 23 | if(image[sr][sc]==color) 24 | return image; 25 | floodfill(sr, sc, color, image[sr][sc], image); 26 | return image; 27 | } 28 | }; 29 | 30 | /* 31 | Time Complexity: O(n*m) 32 | Space Complexity: O(n*m) 33 | */ -------------------------------------------------------------------------------- /Graph/Easy/1. DFS - Evaluate Boolean Binary Tree.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/evaluate-boolean-binary-tree/ 2 | 3 | /** 4 | * Definition for a binary tree node. 5 | * struct TreeNode { 6 | * int val; 7 | * TreeNode *left; 8 | * TreeNode *right; 9 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 10 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 12 | * }; 13 | */ 14 | class Solution { 15 | public: 16 | bool evaluateTree(TreeNode* root) { 17 | if(!root->left && !root->right) { 18 | // root is a leaf node 19 | return root->val; 20 | } 21 | if(root->val==2){ 22 | return evaluateTree(root->left) | evaluateTree(root->right); 23 | } 24 | return evaluateTree(root->left) & evaluateTree(root->right); 25 | } 26 | }; 27 | 28 | /* 29 | Time Complexity: O(n) 30 | Space Complexity: O(n) 31 | */ -------------------------------------------------------------------------------- /Graph/Easy/2. DFS Matrix -Island Perimeter.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/island-perimeter/ 2 | 3 | class Solution { 4 | vector dx={-1, 0, 1, 0}, dy={0, 1, 0, -1}; 5 | void dfs(int i, int j, int &ans, vector> &vis, int &n, int &m, vector>& grid) { 6 | for(int k=0;k<4;k++){ 7 | int ii=i+dx[k], jj=j+dy[k]; 8 | if(ii>=0 && ii=0 && jj>& grid) { 21 | int n=grid.size(), m=grid[0].size(), ans=0; 22 | for(int i=0;i> vis(n, vector(m, false)); 26 | vis[i][j]=true; 27 | dfs(i, j, ans, vis, n, m, grid); 28 | return ans; 29 | } 30 | } 31 | } 32 | return ans; 33 | } 34 | }; 35 | 36 | /* 37 | Time Complexity: O(n*m) 38 | Space Complexity: O(n*m) 39 | */ -------------------------------------------------------------------------------- /Graph/Hard/1. BFS - Word Ladder.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/word-ladder/ 2 | 3 | class Solution { 4 | public: 5 | int ladderLength(string beginWord, string endWord, vector& wordList) { 6 | set words; 7 | int n=beginWord.length(); 8 | for(string &s: wordList) { // O(n*m) 9 | if(s.length()==n) 10 | words.insert(s); // O(1) 11 | } 12 | if(words.find(endWord)==words.end()){ // O(m) 13 | return 0; 14 | } 15 | words.erase(beginWord); // O(m) 16 | 17 | // BFS 18 | queue q; 19 | q.push(beginWord); // O(m) 20 | int ans=0; 21 | 22 | while(!q.empty()){ 23 | int s=q.size(); 24 | ans++; 25 | while(s--){ 26 | string curr=q.front(), temp; 27 | q.pop(); 28 | if(curr==endWord){ 29 | return ans; 30 | } 31 | for(int i=0;i Linear 52 | Space Complexity: O(n*m) -> Linear 53 | */ -------------------------------------------------------------------------------- /Graph/Hard/2. PriorityQueue - Course Schedule III.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/course-schedule-iii/ 2 | 3 | class Solution { 4 | static bool compare(vector &v1, vector &v2){ 5 | return v1[1]> courses) { 9 | int t=0; 10 | int ans=0; 11 | priority_queue q; // stores duration 12 | sort(courses.begin(), courses.end(), compare); 13 | for(auto &c:courses){ 14 | t+=c[0]; 15 | q.push(c[0]); 16 | if(t>c[1]){ 17 | t-=q.top(); 18 | q.pop(); 19 | } 20 | } 21 | return q.size(); 22 | } 23 | }; 24 | 25 | /* 26 | Time Complexity: O(nlogn) 27 | Space Complexity: O(n) 28 | */ -------------------------------------------------------------------------------- /Graph/Hard/3. BFS PriorityQueue - Swim in Rising Water.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/swim-in-rising-water/ 2 | 3 | class Solution { 4 | struct comp{ 5 | bool operator()(vector const&v1, vector const&v2){ 6 | return v1[0]>v2[0]; 7 | } 8 | }; 9 | public: 10 | int swimInWater(vector>& grid) { 11 | vector> seen(grid.size(), vector (grid[0].size(), 0)); 12 | priority_queue< vector, vector >, comp> pq; 13 | pq.push({grid[0][0], 0, 0}); // time, x, y 14 | seen[0][0]=1; 15 | vector dx={-1, 0, 1, 0}, dy={0, -1, 0, 1}; 16 | int ans=INT_MAX; 17 | while(1){ 18 | auto v=pq.top(); 19 | pq.pop(); 20 | int t=v[0]; 21 | // cout<=0 && i=0 && jnewTime){ 29 | newTime=grid[i][j]; 30 | } 31 | pq.push({newTime, i, j}); 32 | seen[i][j]=1; 33 | // cout< &ans, map> &mp){ 7 | auto multi_set=mp[air]; 8 | for(auto &airport:multi_set){ 9 | if(mp[air].find(airport)!=mp[air].end()){ 10 | mp[air].erase(mp[air].find(airport)); 11 | dfs(airport, ans, mp); 12 | } 13 | } 14 | ans.push_back(air); 15 | } 16 | public: 17 | vector findItinerary(vector>& tickets) { 18 | // graph creation 19 | map> mp; 20 | for(auto &t: tickets){ 21 | mp[t[0]].insert(t[1]); 22 | } 23 | 24 | vector ans; 25 | dfs("JFK", ans, mp); 26 | reverse(ans.begin(), ans.end()); 27 | return ans; 28 | } 29 | }; 30 | 31 | /* 32 | n=size of tickets 33 | Time Complexity: O(n) 34 | Space Complexity: O(n) 35 | */ -------------------------------------------------------------------------------- /Graph/Hard/4. Multisource BFS - Shortest Path Visiting All Nodes.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/shortest-path-visiting-all-nodes/ 2 | 3 | /* 4 | Approach: 5 | 1. It says shortest path => BFS 6 | 2. We can visit a node muliple times 7 | 3. We can also visit any edge multiple times 8 | 4. What's unique is that we won't repeat a configuration again 9 | 5. For that we can maintain bitmap 10 | 6. In the BFS, we need to start from every node because we need to catch the shortest path from any node 11 | */ 12 | 13 | class Solution { 14 | public: 15 | int shortestPathLength(vector>& graph) { 16 | int n=graph.size(); 17 | queue> q; 18 | set> st; 19 | for(int i=0;i> &vis, vector > &A, int &m, int &n){ 5 | if(i<=0 || j<=0 || i>=n-1 || j>=m-1){ 6 | return false; 7 | } 8 | // cout<<"step-1 "; 9 | vis[i][j]=true; 10 | A[i][j]='Y'; 11 | // cout<<"step-2 "; 12 | for(int k=0;k<4;k++){ 13 | int nx=dx[k]+i, ny=dy[k]+j; 14 | // cout<<"step-3 "; 15 | if(nx<0 || ny<0 || nx>=n || ny>=m || A[nx][ny]=='Y' || A[nx][ny]=='X'){ 16 | continue; 17 | } 18 | // cout<<"step-4 "; 19 | if(vis[nx][ny] || dfs(nx, ny, vis, A, m, n)==false) 20 | return false; 21 | // cout<<"step-5 "; 22 | } 23 | return true; 24 | } 25 | 26 | void mark_o_to_x(int i, int j, vector > &A, int &m, int &n, char x){ 27 | if(i<=0 || j<=0 || i>=n-1 || j>=m-1){ 28 | return; 29 | } 30 | A[i][j]=x; 31 | for(int k=0;k<4;k++){ 32 | int nx=dx[k]+i, ny=dy[k]+j; 33 | if(nx<0 || ny<0 || nx==n || ny==m || A[nx][ny]==x){ 34 | continue; 35 | } 36 | else if(A[nx][ny]=='Y') 37 | mark_o_to_x(nx, ny, A, m, n, x); 38 | } 39 | } 40 | void Solution::solve(vector > &A) { 41 | // Do not write main() function. 42 | // Do not read input, instead use the arguments to the function. 43 | // Do not print the output, instead return values as specified 44 | // Still have a doubt. Checkout www.interviewbit.com/pages/sample_codes/ for more details 45 | int n=A.size(), m=A[0].size(); 46 | vector> vis(n, vector (m, false)); 47 | 48 | for(int i=0;i sumOfDistancesInTree(int n, vector>& edges) { 7 | // Floyd warshall in tree 8 | long long INF=LONG_MAX; 9 | vector> mat(n, vector (n, INF)); 10 | for(int i=0;i ans; 26 | for(int i=0;i 4 | using namespace std; 5 | 6 | int dx[4]={0, -1, 0, 1}, dy[4]={-1, 0, 1, 0}; 7 | bool dfs(int i, int j, int pos, vector &A, string &B) { 8 | if(i<0 || i>A.size() || j<0 || j>A[i].size()) 9 | return false; 10 | if(pos==B.size()) 11 | return true; 12 | if(B[pos]!=A[i][j]) 13 | return false; 14 | for(int k=0;k<4;k++){ 15 | int nx=dx[k]+i, ny=dy[k]+j; 16 | if(dfs(nx, ny, pos+1, A, B)) 17 | return true; 18 | } 19 | return false; 20 | } 21 | int exist(vector &A, string B) { 22 | // dfs 23 | for(int i=0;i A={"FEDCBECD", "FABBGACG", "CDEDGAEC", "BFFEGGBA", "FCEEAFDA", "AGFADEAC", "ADGDCBAA", "EAABDDFF"}; 36 | string B="BCDCB"; 37 | 38 | cout<>& grid) { 6 | // DP, BFS 7 | // DP will be applied in BFS manner from 1s to all the 0s 8 | int dx[4]={-1, 0, 1, 0}, dy[4]={0, -1, 0, 1}; 9 | int n=grid.size(), m=grid[0].size(); 10 | vector> dist(m, vector (n)); 11 | // DP: pre-storing distances 12 | for(int i=0;i> q; // i, j, distance 25 | q.push({i,j,0}); 26 | while(!q.empty()){ 27 | auto f=q.front(); 28 | int pi=f[0], pj=f[1], distance=f[2]; 29 | q.pop(); 30 | for(int k=0;k<4;k++){ 31 | int ni=dx[k]+pi, nj=dy[k]+pj; 32 | if(ni>=0 && nj>=0 && nidistance+1){ 33 | dist[ni][nj]=distance+1; 34 | q.push({ni, nj, distance+1}); 35 | } 36 | } 37 | } 38 | } 39 | } 40 | } 41 | int ans=0; 42 | for(int i=0;i> &vis, vector> &grid){ 6 | if(i<0 || j<0 || i>=n || j>=m) 7 | return; 8 | if(vis[i][j] || grid[i][j]!=1) 9 | return; 10 | vis[i][j]=1; 11 | grid[i][j]=2; 12 | for(int k=0;k<4;k++){ 13 | dfsConvertTo2(i+dx[k], j+dy[k], m, n, vis, grid); 14 | } 15 | } 16 | public: 17 | int shortestBridge(vector>& grid) { 18 | // Bascially, find the min distance between the 2 islands 19 | // DFS: we can make 2nd island's 1s as 2 20 | int n=grid.size(), m=grid[0].size(); 21 | vector> vis(n, vector (m, false)); 22 | for(int i=0;i> q; 35 | vis.resize(n, vector (m, false)); 36 | 37 | for(int i=0;i=0 && nj>=0 && ni> &vis, vector>& grid1, vector>& grid2) { 6 | if(i<0 || j<0 || i>=n || j>=m || vis[i][j] || grid2[i][j]==0){ 7 | return true; 8 | } 9 | if(grid1[i][j]==0){ 10 | return false; 11 | } 12 | // calculations 13 | vis[i][j]=true; 14 | bool ans=true; // important! to completely traverse component 15 | for(int k=0;k<4;k++){ 16 | int ni=dx[k]+i, nj=dy[k]+j; 17 | if(!dfs(ni, nj, m, n, vis, grid1, grid2)) 18 | ans=false; 19 | } 20 | return ans; 21 | } 22 | public: 23 | int countSubIslands(vector>& grid1, vector>& grid2) { 24 | int n=grid2.size(), m=grid2[0].size(); 25 | vector> vis(n, vector (m, 0)); 26 | int ans=0; 27 | for(int i=0;i dx={-1, 0, 1, 0}, dy={0, 1, 0, -1}; 6 | int m,n; 7 | void dfs(int i, int j, vector>& image, int basecolor, int &color){ 8 | // cout<=n || nj>=m || image[ni][nj]!=basecolor){ 13 | continue; 14 | } 15 | dfs(ni, nj, image, basecolor, color); 16 | } 17 | } 18 | public: 19 | vector> floodFill(vector>& image, int sr, int sc, int color) { 20 | n=image.size(), m=image[0].size(); 21 | if(image[sr][sc]==color) 22 | return image; 23 | dfs(sr, sc, image, image[sr][sc], color); 24 | return image; 25 | } 26 | }; 27 | 28 | /* 29 | Time, Space: O(m*n) 30 | */ -------------------------------------------------------------------------------- /Graph/Leetcode graph theory series/Is Graph Bipartite.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/is-graph-bipartite/ 2 | 3 | // BFS 4 | class Solution { 5 | public: 6 | bool isBipartite(vector>& graph) { 7 | int n=graph.size(); 8 | vector color(n, 0); 9 | for(int node=0;node q; 13 | q.push(node); 14 | color[node]=1; 15 | while(!q.empty()){ 16 | int frontNode=q.front(); 17 | q.pop(); 18 | for(int &nbr: graph[frontNode]){ 19 | if(color[nbr]==color[frontNode]){ 20 | return false; 21 | } 22 | if(color[nbr]==0){ 23 | color[nbr]=-color[frontNode]; 24 | q.push(nbr); 25 | } 26 | } 27 | } 28 | } 29 | return true; 30 | } 31 | }; 32 | /* 33 | Time: O(V+E) 34 | Space: O(V+E) 35 | */ 36 | 37 | // DFS 38 | class Solution { 39 | bool dfs(int node, vector &color, vector>& graph) { 40 | for(int &nbr: graph[node]){ 41 | if(color[nbr]==color[node]) 42 | return false; 43 | if(color[nbr]==0){ 44 | color[nbr]=-color[node]; 45 | if(dfs(nbr, color, graph)==false) 46 | return false; 47 | } 48 | } 49 | return true; 50 | } 51 | public: 52 | bool isBipartite(vector>& graph) { 53 | int n=graph.size(); 54 | vector color(n, 0); 55 | for(int node=0;node par; 79 | DSU(int n){ 80 | par.resize(n); 81 | for(int i=0;i>& graph) { 96 | int n=graph.size(); 97 | DSU dsu(n); 98 | for(int i=0;i>& roads) { 6 | unordered_map> mp; 7 | for(auto &r: roads){ 8 | mp[r[0]].insert(r[1]); 9 | mp[r[1]].insert(r[0]); 10 | } 11 | int ans=0; 12 | for(int i=0;i vis(n, 0); 14 | // connected -> delete repeated network/edge 15 | for(int nbr: mp[i]){ 16 | ans=max(ans, (int)mp[nbr].size()+(int)mp[i].size()-1); 17 | vis[nbr]=1; 18 | } 19 | // disconnected 20 | for(int j=0;j& wordList) { 6 | unordered_set words; 7 | for(auto &s: wordList){ 8 | if(s.length()==beginWord.size()) 9 | words.insert(s); 10 | } 11 | if(words.find(endWord)==words.end()) 12 | return -1; 13 | 14 | priority_queue> q; 15 | map vis; 16 | q.push({0,beginWord}); 17 | vis[beginWord]=0; 18 | while(!q.empty()){ 19 | auto t=q.top(); 20 | int len=-t.first; 21 | string s=t.second; 22 | q.pop(); 23 | // cout<len)){ 33 | q.push({-(len+1), temp}); 34 | vis[temp]=(len+1); 35 | } 36 | } 37 | } 38 | } 39 | return -1; 40 | } 41 | }; 42 | 43 | /* 44 | Time: O(V+E) 45 | Space: O(V+E) 46 | */ -------------------------------------------------------------------------------- /Graph/Leetcode graph theory series/Nearest Exit from Entrance in Maze.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/nearest-exit-from-entrance-in-maze 2 | 3 | class Solution { 4 | public: 5 | int nearestExit(vector>& maze, vector& entrance) { 6 | // BFS 7 | int n=maze.size(), m=maze[0].size(); 8 | int ei=entrance[0], ej=entrance[1]; 9 | queue> q; 10 | vector> vis(n, vector (m, false)); 11 | int ans=0; 12 | int dx[4]={-1, 0, 1, 0}, dy[4]={0, 1, 0, -1}; 13 | 14 | q.push({ei, ej}); 15 | vis[ei][ej]=1; 16 | 17 | while(!q.empty()){ 18 | int s=q.size(); 19 | while(s--){ 20 | auto p=q.front(); 21 | int pi=p.first, pj=p.second; 22 | q.pop(); 23 | if(!(pi==ei && pj==ej) && (pi==0||pj==0||pi==n-1||pj==m-1)){ 24 | return ans; 25 | } 26 | for(int k=0;k<4;k++){ 27 | int ni=dx[k]+pi, nj=dy[k]+pj; 28 | if(ni>=0 && nj>=0 && ni> &vis, vector>& grid){ 6 | if(i<0 || j<0 || i>=n || j>=m) 7 | return false; 8 | 9 | if(vis[i][j] || grid[i][j]) 10 | return true; 11 | vis[i][j]=1; 12 | bool ans=true; 13 | for(int k=0;k<4;k++){ 14 | int ni=dx[k]+i, nj=dy[k]+j; 15 | if(dfs(ni, nj, m, n, vis, grid)==false) 16 | ans=false; 17 | } 18 | return ans; 19 | } 20 | public: 21 | int closedIsland(vector>& grid) { 22 | // basically, 0s neighbors can only be 1s and should not fall on the boundary 23 | int n=grid.size(), m=grid[0].size(); 24 | vector> vis(n, vector (m, 0)); 25 | int ans=0; 26 | // dfs 27 | for(int i=0;i> &vis, vector>& grid, int &siz) { 6 | // returns false if component touches the boundary 7 | if(i<0 || j<0 || i>=n || j>=m){ 8 | return false; 9 | } 10 | // the cases to ignore 11 | if(vis[i][j] || grid[i][j]==0){ 12 | return true; 13 | } 14 | // calculations 15 | siz++; 16 | vis[i][j]=true; 17 | bool ans=true; // important! to completely traverse component 18 | for(int k=0;k<4;k++){ 19 | int ni=dx[k]+i, nj=dy[k]+j; 20 | if(!dfs(ni, nj, m, n, vis, grid, siz)) 21 | ans=false; 22 | } 23 | return ans; 24 | } 25 | public: 26 | int numEnclaves(vector>& grid) { 27 | // Basically, the ques expects us to return no. of 1s in such components who are not touching the boundary 28 | int n=grid.size(), m=grid[0].size(); 29 | vector> vis(n, vector (m, 0)); 30 | int ans; 31 | for(int i=0;i>& grid, vector> &vis){ 6 | if(i<0 || j<0 || i>=n || j>=m || grid[i][j]!='1' || vis[i][j]){ 7 | return; 8 | } 9 | // cout<>& grid) { 18 | int ans=0, n=grid.size(), m=grid[0].size(); 19 | vector> vis(n, vector (m, 0)); 20 | for(int i=0;i& deadends, string target) { 6 | unordered_set deads; 7 | for(string &d:deadends){ 8 | deads.insert(d); 9 | } 10 | // if target is a deadend 11 | if(deads.find(target)!=deads.end()) 12 | return -1; 13 | if(deads.find("0000")!=deads.end()) 14 | return -1; 15 | // BFS 16 | queue q; 17 | q.push("0000"); 18 | int ans=0; 19 | while(!q.empty()){ 20 | int s=q.size(); 21 | // cout<<"\n"; 22 | while(s--){ 23 | string f=q.front(); 24 | // cout<> &vis, vector>& heights, bool pacific) { 6 | if(i<0 || j<0 || i>=n || j>=m || vis[i][j]==2 || heights[i][j]> pacificAtlantic(vector>& heights) { 25 | // imagine the reverse situation 26 | // water is coming to cells and we have to return cells where water is reached from both the oceans 27 | // pacific ocean 28 | int n=heights.size(), m=heights[0].size(); 29 | vector> vis(n, vector (m, 0)); 30 | vector> ans; 31 | // pacific 32 | for(int i=0;i& wordList) { 6 | // BFS with pq 7 | unordered_set words; 8 | for(auto &s: wordList){ 9 | if(s.length()==beginWord.size()) 10 | words.insert(s); 11 | } 12 | if(words.find(endWord)==words.end()) 13 | return 0; 14 | 15 | priority_queue> q; 16 | map vis; 17 | q.push({-1,beginWord}); 18 | vis[beginWord]=1; 19 | while(!q.empty()){ 20 | auto t=q.top(); 21 | int len=-t.first; 22 | string s=t.second; 23 | q.pop(); 24 | // cout<len)){ 34 | q.push({-(len+1), temp}); 35 | vis[temp]=(len+1); 36 | } 37 | } 38 | } 39 | } 40 | return 0; 41 | } 42 | }; 43 | 44 | /* 45 | Time: O(V+E) 46 | Space: O(V+E) 47 | */ -------------------------------------------------------------------------------- /Graph/Medium/1. Adjacency List - Minimum Number of Vertices to Reach All Nodes.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/minimum-number-of-vertices-to-reach-all-nodes/ 2 | 3 | class Solution { 4 | public: 5 | vector findSmallestSetOfVertices(int n, vector>& edges) { 6 | vector in(n, 0); 7 | for(auto &e: edges){ 8 | in[e[1]]++; 9 | } 10 | vector ans; 11 | for(int i=0;i>& prerequisite) { 6 | // No cycle should be there 7 | // There should be a valid Topological sort in order to return true 8 | vector inDeg(n); 9 | unordered_map> prereq; 10 | for(auto &p: prerequisite){ 11 | inDeg[p[0]]++; 12 | prereq[p[1]].push_back(p[0]); 13 | } 14 | queue q; 15 | vector vis(n, false); 16 | for(int i=0;i findOrder(int n, vector>& prerequisites) { 6 | // Topological sort 7 | unordered_map> prereq; 8 | vector inDeg(n, 0); 9 | for(auto &courses: prerequisites){ 10 | prereq[courses[1]].push_back(courses[0]); // implies course[0] should be ompleted first and then course[1] can be completed 11 | inDeg[courses[0]]++; 12 | } 13 | // insert all the courses with no prerequisite in a queue 14 | queue q; 15 | for(int i=0;i ans; 22 | while(!q.empty()){ 23 | int courseNo=q.front(); 24 | q.pop(); 25 | ans.push_back(courseNo); 26 | for(int &course: prereq[courseNo]){ 27 | inDeg[course]--; 28 | if(inDeg[course]==0){ 29 | q.push(course); 30 | } 31 | } 32 | } 33 | for(int i=0;i par, rank; 10 | DSU(int n){ 11 | par.resize(n+1); 12 | rank.resize(n+1, 1); 13 | for(int i=1;i<=n;i++) 14 | par[i]=i; 15 | } 16 | void Union(int a, int b){ 17 | int par_a=Find(a); 18 | int par_b=Find(b); 19 | if(par_a!=par_b){ 20 | if(rank[par_a]<=rank[par_b]){ 21 | par[par_a]=par_b; 22 | rank[par_b]+=rank[par_a]; 23 | } 24 | else{ 25 | par[par_b]=par_a; 26 | rank[par_a]+=rank[par_b]; 27 | } 28 | } 29 | } 30 | int Find(int a){ 31 | if(a==par[a]) 32 | return a; 33 | return par[a]=Find(par[a]); 34 | } 35 | }; 36 | class Solution { 37 | public: 38 | int longestConsecutive(vector& nums) { 39 | int n=nums.size(); 40 | DSU dsu(n); 41 | map mp; 42 | for(int i=0;i dx={-1, 0, 1, 0}, dy={0, 1, 0, -1}; 5 | void dfs(int i, int j, int &n, int &m, vector>& board, vector> &vis){ 6 | // cout<=m || i>=n || board[i][j]!='O' || vis[i][j]){ 8 | return; 9 | } 10 | board[i][j]='_'; 11 | vis[i][j]=true; 12 | for(int k=0;k<4;k++){ 13 | dfs(i+dx[k], j+dy[k], n, m, board, vis); 14 | } 15 | } 16 | public: 17 | void solve(vector>& board) { 18 | int n=board.size(), m=board[0].size(); 19 | vector> vis(n, vector (m, 0)); 20 | // Step-1: Pick up all the border "O" and mark each "O" in their component as "_" 21 | for(int i=0;i "X" 39 | for(int i=0;i "O" 48 | for(int i=0;i neighbors; 9 | Node() { 10 | val = 0; 11 | neighbors = vector(); 12 | } 13 | Node(int _val) { 14 | val = _val; 15 | neighbors = vector(); 16 | } 17 | Node(int _val, vector _neighbors) { 18 | val = _val; 19 | neighbors = _neighbors; 20 | } 21 | }; 22 | */ 23 | 24 | class Solution { 25 | map copy; 26 | public: 27 | Node* cloneGraph(Node* node) { 28 | if(!node) 29 | return node; 30 | if(copy.find(node)==copy.end()){ 31 | copy[node]=new Node(node->val, {}); 32 | for(auto &n: node->neighbors){ 33 | copy[node]->neighbors.push_back(cloneGraph(n)); 34 | } 35 | } 36 | return copy[node]; 37 | } 38 | }; 39 | 40 | /* 41 | n=number of nodes 42 | Time Complexity: O(n) 43 | Space Complexity: O(n) 44 | */ -------------------------------------------------------------------------------- /Graph/Medium/2. Adjacency List - Maximum Total Importance of Roads.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/maximum-total-importance-of-roads/ 2 | 3 | class Solution { 4 | public: 5 | long long maximumImportance(int n, vector>& roads) { 6 | vector in(n, 0); 7 | for(auto &e: roads){ 8 | in[e[1]]++; 9 | in[e[0]]++; 10 | } 11 | 12 | sort(in.begin(), in.end()); 13 | 14 | long long int ans=0; 15 | for(int i=0;i findMinHeightTrees(int n, vector>& edge) { 6 | if(n==1) 7 | return {0}; 8 | unordered_map> mp; 9 | for(auto &e: edge){ 10 | mp[e[0]].insert(e[1]); 11 | mp[e[1]].insert(e[0]); 12 | } 13 | queue q; 14 | for(auto &e:mp){ 15 | if(e.second.size()==1) 16 | q.push(e.first); 17 | } 18 | 19 | while(!q.empty()){ 20 | int s=q.size(); 21 | if(n<=2){ 22 | break; 23 | } 24 | while(s--){ 25 | int f=q.front(); 26 | q.pop(); 27 | for(auto &e: mp[f]){ 28 | mp[e].erase(f); 29 | if(mp[e].size()==1){ 30 | q.push(e); 31 | } 32 | } 33 | n--; 34 | } 35 | } 36 | vector ans; 37 | while(q.size()){ 38 | ans.push_back(q.front()); 39 | q.pop(); 40 | } 41 | return ans; 42 | } 43 | }; 44 | 45 | /* 46 | Time Complexity: O(n) 47 | Space Complexity: O(n) 48 | */ -------------------------------------------------------------------------------- /Graph/Medium/4. UnionFind.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/find-if-path-exists-in-graph/ 2 | 3 | class Solution { 4 | vector par, rank; 5 | void Union(int a, int b){ 6 | int par_a=Find(a); 7 | int par_b=Find(b); 8 | // Note that parent or parent is attached to other's parent and not the parent of child 9 | if(par_a!=par_b){ 10 | if(rank[a]>rank[b]){ 11 | par[par_b]=par_a; 12 | rank[par_a]++; 13 | } 14 | else{ 15 | par[par_a]=par_b; 16 | rank[par_b]++; 17 | } 18 | } 19 | } 20 | int Find(int a){ 21 | if(a==par[a]) 22 | return a; 23 | return par[a]=Find(par[a]); 24 | } 25 | public: 26 | bool validPath(int n, vector>& edges, int src, int dest) { 27 | par.resize(n, 0); 28 | rank.resize(n, 1); 29 | for(int i=0;i par, rank; 5 | public: 6 | DSU(int n){ 7 | par.resize(n+1); 8 | rank.resize(n+1, 1); 9 | for(int i=1;i<=n;i++) 10 | par[i]=i; 11 | } 12 | void Union(int a, int b){ 13 | int par_a=Find(a); 14 | int par_b=Find(b); 15 | if(par_a!=par_b){ 16 | if(rank[a] findRedundantConnection(vector>& edges) { 35 | int n=edges.size(); 36 | DSU dsu(2*n); 37 | vector ans; 38 | for(auto &e: edges){ 39 | int a=e[0], b=e[1]; 40 | int par_a=dsu.Find(a); 41 | int par_b=dsu.Find(b); 42 | if(par_a!=par_b){ 43 | dsu.Union(par_a, par_b); 44 | } 45 | else{ 46 | ans=e; 47 | } 48 | } 49 | return ans; 50 | } 51 | }; 52 | 53 | /* 54 | Time Complexity: O(n) 55 | Space Complexity: O(n) 56 | */ -------------------------------------------------------------------------------- /Graph/Medium/6. DFS - Number of Enclaves.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/number-of-enclaves/ 2 | 3 | class Solution { 4 | vector dx = {-1, 0, 1, 0}, dy={0, 1, 0, -1}; 5 | 6 | void dfs(int i, int j, int &n, int&m, vector>& grid) { 7 | if(i<0 || i>=n || j<0 || j>=m || grid[i][j]!=1){ 8 | return; 9 | } 10 | grid[i][j]=2; 11 | for(int k=0;k<4;k++){ 12 | dfs(i+dx[k], j+dy[k], n, m, grid); 13 | } 14 | } 15 | public: 16 | int numEnclaves(vector>& grid) { 17 | int n=grid.size(), m=grid[0].size(); 18 | for(int i=0;i>& grid) { 5 | if(i<0 || j<0 || i>=n || j>=m || grid[i][j]!=0) 6 | return; 7 | grid[i][j]=2; 8 | dfs(i+1, j, n, m, grid); 9 | dfs(i-1, j, n, m, grid); 10 | dfs(i, j+1, n, m, grid); 11 | dfs(i, j-1, n, m, grid); 12 | } 13 | public: 14 | int closedIsland(vector> grid) { 15 | int n=grid.size(), m=grid[0].size(); 16 | // step-1: 17 | // all 0s at the boundary and their connected groups will be 1s 18 | // because have a non-1 boundary, that is sea 19 | 20 | for(int i=0;i 4 | using namespace std; 5 | 6 | void dfs(int i, int &count, vector &vis, unordered_map> &mp) { 7 | count++; 8 | vis[i]=1; 9 | for(auto &a: mp[i]){ 10 | if(!vis[a]){ 11 | dfs(a, count, vis, mp); 12 | } 13 | } 14 | } 15 | 16 | int main() { 17 | /* Enter your code here. Read input from STDIN. Print output to STDOUT */ 18 | int n, p, a, b; 19 | cin>>n>>p; 20 | unordered_map> mp; 21 | for(int i=0;i>a>>b; 23 | mp[a].push_back(b); 24 | mp[b].push_back(a); 25 | } 26 | vector ans; 27 | vector vis(n, false); 28 | for(int i=0;ival>=maxLimit || root->val<=minLimit){ 21 | return false; 22 | } 23 | return isValidBST(root->left, minLimit, min(maxLimit, (long long)root->val))&&isValidBST(root->right, max(minLimit, (long long)root->val), maxLimit); 24 | } 25 | }; 26 | 27 | /* 28 | n=number of nodes 29 | Time Complexity: O(n) 30 | Space Complexity: O(n) 31 | */ -------------------------------------------------------------------------------- /Hashing/1. Hashing - Valid Sudoku.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/valid-sudoku/ 2 | 3 | class Solution { 4 | public: 5 | bool isValidSudoku(vector>& nums) { 6 | map> mp_row, mp_col; 7 | map, unordered_set> mp_box; 8 | int n=nums.size(), m=nums[0].size(); 9 | for(int i=0;i& nums) { 6 | set st; 7 | for(int i=0;i& startWords, vector& targetWords) { 6 | if(targetWords.size() && startWords.size()==0) 7 | return -1; 8 | if(targetWords.size()==0) 9 | return 0; 10 | // we can use sets 11 | set> s; 12 | for(string &word: startWords){ 13 | set temp; 14 | for(char &c: word) 15 | temp.insert(c); 16 | s.insert(temp); 17 | } 18 | int ans=0; 19 | for(string &word: targetWords){ 20 | set ms; 21 | for(char &c: word){ 22 | ms.insert(c); 23 | } 24 | for(char &c:word){ 25 | // auto it = ms.find(c); 26 | ms.erase(c); 27 | if(s.find(ms)!=s.end()){ 28 | ans++; 29 | break; 30 | } 31 | ms.insert(c); 32 | } 33 | } 34 | return ans; 35 | } 36 | }; 37 | 38 | /* 39 | ns=no. of words in startWords array 40 | ls=length of the longest words in startWords 41 | nt=no. of words in targetWords array 42 | lt=length of the longest words in targetWords 43 | Time: O(ns*ls + nt*lt) 44 | Space: O(ns*ls + nt*lt) 45 | */ -------------------------------------------------------------------------------- /Heap or Priority Queue/Find Median from Data Stream.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/find-median-from-data-stream/ 2 | 3 | class MedianFinder { 4 | priority_queue lpq; 5 | priority_queue, greater> hpq; 6 | public: 7 | MedianFinder() { 8 | } 9 | 10 | void addNum(int num) { 11 | // we are always mainting such that we can directly fetch median 12 | // from the top of hpq if the count is odd 13 | hpq.push(num); 14 | 15 | // size diff is 2, making lpq size = hpq size - 1 16 | if(lpq.size()addNum(num); 47 | * double param_2 = obj->findMedian(); 48 | */ 49 | 50 | /* 51 | Time: O(logn) for addNum, O(1) for findMedian 52 | Space: O(n) 53 | */ -------------------------------------------------------------------------------- /Linked List/1. LinkedList - Merge k Sorted Lists.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/merge-k-sorted-lists/ 2 | 3 | /* 4 | We use priority queue as it'll prioritize which list's node would first get included 5 | */ 6 | 7 | /** 8 | * Definition for singly-linked list. 9 | * struct ListNode { 10 | * int val; 11 | * ListNode *next; 12 | * ListNode() : val(0), next(nullptr) {} 13 | * ListNode(int x) : val(x), next(nullptr) {} 14 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 15 | * }; 16 | */ 17 | class Solution { 18 | struct comp{ 19 | bool operator()(ListNode* &l1, ListNode* &l2){ 20 | return l1->val>=l2->val; 21 | } 22 | }; 23 | public: 24 | ListNode* mergeKLists(vector& lists) { 25 | // LL + PQ 26 | // PQ will keep nodes acc to their inc order of value 27 | ListNode* newList=new ListNode(); 28 | auto temp=newList; 29 | priority_queue, comp> pq; 30 | for(ListNode* node: lists){ 31 | if(node) 32 | pq.push(node); 33 | } 34 | while(!pq.empty()){ 35 | ListNode* node=pq.top(); 36 | pq.pop(); 37 | // cout<val; 38 | temp->next=node; 39 | temp=temp->next; 40 | if(node->next){ 41 | pq.push(node->next); 42 | } 43 | } 44 | return newList->next; 45 | } 46 | }; 47 | 48 | /* 49 | Time Complexity: O(nlogk) -> Priority queue takes O(logk) 50 | Space Complexity: O(n) 51 | */ -------------------------------------------------------------------------------- /Linked List/2. Maximum Twin Sum of a Linked List.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/maximum-twin-sum-of-a-linked-list/ 2 | 3 | /** 4 | * Definition for singly-linked list. 5 | * struct ListNode { 6 | * int val; 7 | * ListNode *next; 8 | * ListNode() : val(0), next(nullptr) {} 9 | * ListNode(int x) : val(x), next(nullptr) {} 10 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 11 | * }; 12 | */ 13 | class Solution { 14 | void help(ListNode* node, ListNode* &node2, int &ans) { 15 | if(!node || !node2){ 16 | return; 17 | } 18 | help(node->next, node2, ans); 19 | // cout<val<<" "<val<<"\n"; 20 | int sum=node->val+node2->val; 21 | ans=max(ans, sum); 22 | node2=node2->next; 23 | } 24 | public: 25 | int pairSum(ListNode* head) { 26 | int ans=0; 27 | help(head, head, ans); 28 | return ans; 29 | } 30 | }; 31 | 32 | /* 33 | Time: O(n) 34 | Space: O(n) 35 | */ -------------------------------------------------------------------------------- /Minimum Spanning Tree/Kruskal's - Min Cost to Connect All Points.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/min-cost-to-connect-all-points/ 2 | // prerequisite: https://www.youtube.com/watch?v=fAuF0EuZVCk&list=PLrmLmBdmIlpu2f2g8ltqaaCZiq6GJvl1j&index=4&ab_channel=TusharRoy-CodingMadeSimple 3 | 4 | class Solution { 5 | class DSU{ 6 | vector par; 7 | public: 8 | DSU(int &n){ 9 | par.resize(n); 10 | for(int i=0;i>& points) { 24 | // step-1 : forming edges with cost 25 | // index the points 26 | int k=0; 27 | unordered_map> idxToPoint; 28 | map, int> pointToIdx; 29 | for(auto &p: points){ 30 | if(pointToIdx.count({p[0],p[1]})) 31 | continue; 32 | pointToIdx[{p[0],p[1]}]=k; 33 | idxToPoint[k++]={p[0],p[1]}; 34 | } 35 | 36 | // we have in total k unique points 37 | // now we would find and store dist of each point to one another in graph 38 | vector>> edges; 39 | // {{dist12, idx1, idx2}} 40 | for(int i=1;i p1=idxToPoint[i], p2=idxToPoint[j]; 43 | int dist=abs(p1.first-p2.first)+abs(p1.second-p2.second); 44 | edges.push_back({dist, {i, j}}); 45 | } 46 | } 47 | sort(edges.begin(), edges.end()); 48 | 49 | // step-2 : DSU 50 | DSU dsu(k); 51 | 52 | // step-3 : Kruskal's 53 | int ans=0; 54 | for(auto &e: edges){ 55 | int a=e.second.first, b=e.second.second; 56 | a=dsu.find(a), b=dsu.find(b); 57 | if(a==b) 58 | continue; // same group forms cycle 59 | ans+=e.first; 60 | dsu.union_(a, b); 61 | } 62 | return ans; 63 | } 64 | }; -------------------------------------------------------------------------------- /Mixed/1. Find Original Array From Doubled Array.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/find-original-array-from-doubled-array/ 2 | 3 | class Solution { 4 | public: 5 | vector findOriginalArray(vector& changed) { 6 | vector ans; 7 | // base condition 8 | if(changed.size()%2){ 9 | // cannot be doubled array 10 | return ans; 11 | } 12 | 13 | // sort 14 | sort(changed.begin(), changed.end()); 15 | int n=changed.size(); 16 | 17 | multimap mp; 18 | 19 | for(int i=0;i>& grid) { 6 | int n=grid.size(), m=grid[0].size(); 7 | 8 | // index grid elements 9 | map mpR, mpC; 10 | int k=0; 11 | for(int i=0;i1 || mpC[j]>1) 24 | ans++; 25 | } 26 | } 27 | } 28 | return ans; 29 | } 30 | }; 31 | 32 | /* 33 | Time: O(n*m) 34 | Space: O(max(n, m)) 35 | */ -------------------------------------------------------------------------------- /Mixed/11. Number of Operations to Make Network Connected.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/number-of-operations-to-make-network-connected/ 2 | 3 | class Solution { 4 | int find(int a, vector &par){ 5 | if(a==par[a]) 6 | return a; 7 | return par[a]=find(par[a], par); 8 | } 9 | void union_(int a, int b, vector &par, vector &rank){ 10 | if(rank[b]>rank[a]){ 11 | par[a]=b; 12 | rank[b]++; 13 | } 14 | else{ 15 | par[b]=a; 16 | rank[a]++; 17 | } 18 | } 19 | public: 20 | int makeConnected(int n, vector>& connections) { 21 | // basically 22 | // we need to find out the number of redundent connections 23 | // there are n servers and m connections 24 | int m=connections.size(); 25 | if(m par(n), rank(n, 1); 32 | for(int i=0;i> s; 6 | public: 7 | 8 | /*returns min element from stack*/ 9 | int getMin(){ 10 | 11 | //Write your code here 12 | if(s.empty()) 13 | return -1; 14 | return s.top().second; 15 | } 16 | 17 | /*returns poped element from stack*/ 18 | int pop(){ 19 | 20 | //Write your code here 21 | if(s.empty()) 22 | return -1; 23 | auto a=s.top(); 24 | s.pop(); 25 | return a.first; 26 | } 27 | 28 | /*push element x into the stack*/ 29 | void push(int x){ 30 | 31 | //Write your code here 32 | if(s.empty()){ 33 | s.push({x, x}); 34 | } 35 | else if(s.top().second>=x){ 36 | s.push({x,x}); 37 | } 38 | else{ 39 | s.push({x, s.top().second}); 40 | } 41 | } 42 | }; 43 | 44 | /* 45 | Time: O(1) 46 | Space: O(1) 47 | */ -------------------------------------------------------------------------------- /Mixed/13. Subrectangle Queries.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/subrectangle-queries/ 2 | 3 | class SubrectangleQueries { 4 | vector> rectangle; 5 | public: 6 | SubrectangleQueries(vector>& rectangle) { 7 | this->rectangle=rectangle; 8 | } 9 | 10 | void updateSubrectangle(int row1, int col1, int row2, int col2, int newValue) { 11 | for(int i=row1;i<=row2;i++){ 12 | for(int j=col1; j<=col2; j++){ 13 | rectangle[i][j]=newValue; 14 | } 15 | } 16 | 17 | } 18 | 19 | int getValue(int row, int col) { 20 | return rectangle[row][col]; 21 | } 22 | }; 23 | 24 | /** 25 | * Your SubrectangleQueries object will be instantiated and called as such: 26 | * SubrectangleQueries* obj = new SubrectangleQueries(rectangle); 27 | * obj->updateSubrectangle(row1,col1,row2,col2,newValue); 28 | * int param_2 = obj->getValue(row,col); 29 | */ 30 | 31 | /* 32 | Time: O(n*m) 33 | Space: O(n*m) 34 | (getValue -> O(1)) 35 | */ -------------------------------------------------------------------------------- /Mixed/14. Max Increase to Keep City Skyline.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/max-increase-to-keep-city-skyline/ 2 | 3 | class Solution { 4 | public: 5 | int maxIncreaseKeepingSkyline(vector>& grid) { 6 | int n=grid.size(), m=grid[0].size(); 7 | auto temp=grid; 8 | // north 9 | for(int j=m-1;j>=0;j--){ 10 | int mm=0; 11 | for(int i=0;i& nums) { 6 | // the bitwise AND of n numbers will atmost be n 7 | // the max bitwise of n numbers will be the case when only the maximum number is present 8 | // that's why we would only include the maximum element 9 | int max_=*max_element(nums.begin(), nums.end()); 10 | int ans=0, temp=0; 11 | int i=0, n=nums.size(); 12 | while(i>& roads) { 8 | // code here 9 | // create a graph 10 | map>> mp; 11 | for(auto &a: roads){ 12 | mp[a[0]].push_back({a[1], a[2]}); 13 | mp[a[1]].push_back({a[0], a[2]}); 14 | } 15 | 16 | if(mp.find(0)==mp.end() || mp.find(n-1)==mp.end()) 17 | return 0; 18 | 19 | // 0 to n-1 20 | // bfs + priority queue + dp 21 | 22 | vector ways(n, 0); 23 | vector dist(n, INT_MAX); 24 | const int mod=1e9+7; 25 | ways[0]=1; 26 | dist[0]=0; 27 | 28 | priority_queue, vector>, greater>> pq; 29 | // time, node 30 | pq.push({0, 0}); 31 | 32 | while(!pq.empty()) { 33 | auto t=pq.top(); 34 | ll time=t[0], node=t[1]; 35 | pq.pop(); 36 | 37 | // if we are reaching the node in a longer time than we can 38 | if(time>dist[node]) continue; 39 | 40 | // we are at node n1 41 | for(auto &a: mp[node]){ 42 | // if we can get there in a better time 43 | // relaxing distance in Djikstra 44 | if(dist[a[0]]>time+a[1]){ 45 | dist[a[0]]=time+a[1]; 46 | ways[a[0]]=ways[node]; 47 | pq.push({dist[a[0]], a[0]}); 48 | } 49 | // else if = found min dist 50 | else if(dist[a[0]]==time+a[1]){ 51 | ways[a[0]]=(ways[a[0]]+ways[node])%mod; 52 | } 53 | } 54 | } 55 | 56 | return ways[n-1]; 57 | } 58 | }; 59 | 60 | /* 61 | Time complexity: O(n) 62 | Space complexity: O(n) 63 | */ -------------------------------------------------------------------------------- /Mixed/6. Binary Decimal Conversion.cpp: -------------------------------------------------------------------------------- 1 | // https://practice.geeksforgeeks.org/contest/interview-series-68/problems/# 2 | 3 | class Solution { 4 | 5 | public: 6 | int noConseBits(int query) { 7 | // 7->111 8 | // 111->110 = 6 9 | // 1111111 -> 1101101 > 0110110 10 | // highest priority is to unset it from rightmost to leftmost 11 | // binary conversion 12 | if(query==0) 13 | return 0; 14 | int q=query; 15 | string bin; 16 | while(q){ 17 | if(q&1){ 18 | bin+='1'; 19 | } 20 | else{ 21 | bin+='0'; 22 | } 23 | q=q>>1; 24 | } 25 | 26 | reverse(bin.begin(), bin.end()); 27 | 28 | stack st; 29 | for(int i=0;i dx={-1, 0, 1, 0}, dy={0, 1, 0, -1}; 5 | void dfs(int i, int j, int &size, 6 | vector>& vis, int &m, int &n, vector>& grid) 7 | { 8 | if( i<0 || j<0 || i>=n || j>=m || vis[i][j] || grid[i][j]!=1){ 9 | return; 10 | } 11 | 12 | size++; 13 | vis[i][j]=1; 14 | 15 | for(int k=0;k<4;k++){ 16 | int newi=i+dx[k], newj=j+dy[k]; 17 | dfs(newi, newj, size, vis, m, n, grid); 18 | } 19 | } 20 | public: 21 | int maxAreaOfIsland(vector>& grid) { 22 | int ans=0; 23 | int n=grid.size(), m=grid[0].size(); 24 | 25 | int size=0; 26 | vector> vis(n, vector (m, 0)); 27 | for(int i=0;i>& points) { 30 | // union find 31 | int n=points.size(); 32 | UnionFind uf(n); 33 | 34 | // indexing the points 35 | map, int> idx; 36 | int i=0; 37 | for(int i=0;i>> mp; 45 | // > 46 | 47 | for(int i=0;i par, rank; 5 | public: 6 | DSU(int n){ 7 | par.resize(n); 8 | rank.resize(n); 9 | for(int i=0;i=rank[a]){ 22 | // b dominates 23 | rank[b]+=rank[a]; 24 | par[a]=b; 25 | } 26 | else{ 27 | rank[a]+=rank[b]; 28 | par[b]=a; 29 | } 30 | } 31 | int res(int n){ 32 | int ans=0; 33 | for(int i=0;i& nums) { 43 | int n=nums.size(); 44 | // we union the indices 45 | DSU dsu(n); 46 | 47 | unordered_map mp; 48 | for(int i=0;i vis; 55 | for(int i=0;i table; 7 | int k=0; 8 | for(char &c: key){ 9 | if(c!=' ' && table.find(c)==table.end()){ 10 | table[c]=k++; 11 | } 12 | } 13 | string ans; 14 | for(auto &m: message){ 15 | if(m==' ') 16 | ans+=' '; 17 | else 18 | ans+=table[m]+'a'; 19 | } 20 | return ans; 21 | } 22 | }; 23 | 24 | /* 25 | n=size of key 26 | Time Complexity: O(n) 27 | Space Complexity: O(n) 28 | */ -------------------------------------------------------------------------------- /Mixed/Easy/2. Minimum Hours of Training to Win a Competition.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/minimum-hours-of-training-to-win-a-competition/ 2 | 3 | class Solution { 4 | public: 5 | int minNumberOfHours(int initialEnergy, int initialExperience, vector& energy, vector& experience) { 6 | int ans=0; 7 | for(int i=0;i averageOfLevels(TreeNode* root) { 17 | // bfs 18 | queue q; 19 | q.push(root); 20 | 21 | vector ans; 22 | while(!q.empty()){ 23 | int s=q.size(); 24 | int S=s; 25 | double d=0; 26 | while(s--){ 27 | TreeNode* f=q.front(); 28 | q.pop(); 29 | d+=f->val; 30 | if(f->right) q.push(f->right); 31 | if(f->left) q.push(f->left); 32 | } 33 | d/=S; 34 | ans.push_back(d); 35 | } 36 | return ans; 37 | } 38 | }; 39 | 40 | /* 41 | Time Complexity: O(2^n) 42 | Space Complexity: O(2^n) 43 | */ -------------------------------------------------------------------------------- /Mixed/Easy/4. Construct String from Binary Tree.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/construct-string-from-binary-tree/ 2 | 3 | /** 4 | * Definition for a binary tree node. 5 | * struct TreeNode { 6 | * int val; 7 | * TreeNode *left; 8 | * TreeNode *right; 9 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 10 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 12 | * }; 13 | */ 14 | class Solution { 15 | void help(TreeNode* root, string &ans){ 16 | if(!root) 17 | return; 18 | 19 | ans+=to_string(root->val); 20 | 21 | if(root->left || root->right){ 22 | ans+='('; 23 | help(root->left, ans); 24 | ans+=')'; 25 | } 26 | if(root->right){ 27 | ans+='('; 28 | help(root->right, ans); 29 | ans+=')'; 30 | } 31 | } 32 | public: 33 | string tree2str(TreeNode* root) { 34 | if(!root) 35 | return ""; 36 | 37 | string ans; 38 | help(root, ans); 39 | 40 | return ans; 41 | } 42 | }; 43 | 44 | 45 | /* 46 | Time Complexity: O(n) 47 | Space Complexity: O(n) 48 | */ -------------------------------------------------------------------------------- /Mixed/Hard/4. DFS + DP - Number of Increasing Paths in a Grid.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/number-of-increasing-paths-in-a-grid/ 2 | 3 | class Solution { 4 | const int mod=1e9+7; 5 | vector> dp; 6 | int dfs(int i, int j, int prev, vector>& grid){ 7 | if(min(i, j)<0 || i>=grid.size() || j>=grid[0].size() || grid[i][j]<=prev) 8 | return 0; 9 | return dp[i][j] ?: dp[i][j]=(1+dfs(i+1, j, grid[i][j], grid)+dfs(i, j+1, grid[i][j], grid)+dfs(i-1, j, grid[i][j], grid)+dfs(i, j-1, grid[i][j], grid))%mod; 10 | } 11 | public: 12 | int countPaths(vector>& grid) { 13 | int n=grid.size(), m=grid[0].size(); 14 | dp.resize(n, vector (m, 0)); 15 | int ans=0; 16 | for(int i=0;i>> &mp, int lvl, int depth){ 16 | if(!root) 17 | return; 18 | mp[lvl].push_back({depth, root->val}); 19 | // 0: {0, 1} {2, 5} 20 | // -1: {1, 2} 21 | // -2: {2, 4} 22 | // 1: {1, 4} 23 | // 0: {2, 6} 24 | // 2: {2, 7} 25 | 26 | help(root->left, mp, lvl-1, depth+1); 27 | help(root->right, mp, lvl+1, depth+1); 28 | } 29 | public: 30 | vector> verticalTraversal(TreeNode* root) { 31 | map>> mp; 32 | help(root, mp, 0, 0); 33 | for(auto &a: mp) 34 | sort(a.second.begin(), a.second.end()); 35 | vector> ans; 36 | for(auto &a: mp){ 37 | vector temp; 38 | for(auto &b: a.second) 39 | temp.push_back(b[1]); 40 | ans.push_back(temp); 41 | } 42 | return ans; 43 | } 44 | }; 45 | 46 | /* 47 | Time Complexity: O(n) 48 | Space Complexity: O(n) 49 | */ -------------------------------------------------------------------------------- /Mixed/Medium/10. Count Good Nodes in Binary Tree.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/count-good-nodes-in-binary-tree/ 2 | 3 | /** 4 | * Definition for a binary tree node. 5 | * struct TreeNode { 6 | * int val; 7 | * TreeNode *left; 8 | * TreeNode *right; 9 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 10 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 12 | * }; 13 | */ 14 | class Solution { 15 | void dfs(int &cnt, TreeNode* node, int highest){ 16 | if(!node){ 17 | return; 18 | } 19 | if(node->val>=highest){ 20 | cnt++; 21 | } 22 | dfs(cnt, node->left, max(highest, node->val)); 23 | dfs(cnt, node->right, max(highest, node->val)); 24 | } 25 | public: 26 | int goodNodes(TreeNode* root) { 27 | // dfs 28 | int cnt=0; 29 | dfs(cnt, root, root->val); 30 | return cnt; 31 | } 32 | }; 33 | 34 | 35 | /* 36 | Time Complexity: O(n) 37 | Space Complexity: O(logn) 38 | */ -------------------------------------------------------------------------------- /Mixed/Medium/2. Matrix Traversal - Spiral Matrix IV.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/spiral-matrix-iv/ 2 | 3 | /** 4 | * Definition for singly-linked list. 5 | * struct ListNode { 6 | * int val; 7 | * ListNode *next; 8 | * ListNode() : val(0), next(nullptr) {} 9 | * ListNode(int x) : val(x), next(nullptr) {} 10 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 11 | * }; 12 | */ 13 | class Solution { 14 | public: 15 | vector> spiralMatrix(int m, int n, ListNode* head) { 16 | vector> ans(m, vector (n, -1)); 17 | int maxm=m, maxn=n, minm=0, minn=0; 18 | int dir=0; 19 | // 0=right, 1=down, 2=left, 3=up 20 | int i=0, j=0; 21 | while(head){ 22 | // calculate i and j 23 | // m*n 24 | // cout<val; 26 | if(dir==0){ 27 | if(jminn) 40 | j--; 41 | else 42 | dir=3, i--, maxm--; 43 | } 44 | else{ 45 | if(i>minm) 46 | i--; 47 | else 48 | dir=0, j++, minn++; 49 | } 50 | head=head->next; 51 | } 52 | return ans; 53 | } 54 | }; 55 | 56 | /* 57 | Time Complexity: O(m*n) 58 | Space Complexity: O(m*n) 59 | */ -------------------------------------------------------------------------------- /Mixed/Medium/3. DP - Number of People Aware of a Secret.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/number-of-people-aware-of-a-secret 2 | 3 | class Solution { 4 | public: 5 | int peopleAwareOfSecret(int n, int delay, int forget) { 6 | vector dp(forget, 0); 7 | const int mod=1e9+7; 8 | dp[forget-1]=1; 9 | n--; 10 | while(n--){ 11 | for(int i=0;i mp; 7 | // time: O(1), space: O(10) 8 | for(char c:num){ 9 | mp[c-'0']++; 10 | } 11 | if(mp.size()==1){ 12 | if(num[0]!='0') 13 | return num; 14 | return "0"; 15 | } 16 | priority_queue even, one; 17 | 18 | // time: O(10log10) 19 | for(auto &a:mp){ 20 | // cout<1) 24 | even.push(a.first); 25 | } 26 | else{ 27 | even.push(a.first); 28 | } 29 | } 30 | 31 | // base case 32 | string ans; 33 | if(even.size() && even.top()==0){ 34 | ans=(one.top()+'0'); 35 | return ans; 36 | } 37 | 38 | // time: O(10*n) 39 | while(!even.empty()){ 40 | int a=even.top(); 41 | even.pop(); 42 | int half=mp[a]/2; 43 | while(half--) 44 | ans+=(a+'0'); 45 | } 46 | string temp=ans; 47 | 48 | // time: O(n) 49 | reverse(temp.begin(), temp.end()); 50 | if(one.size()){ 51 | ans+=(one.top()+'0'); 52 | } 53 | ans+=temp; 54 | return ans; 55 | } 56 | }; 57 | 58 | /* 59 | Note that we can also loop ver numbers 0 to 9 ans avoid priority queue 60 | Time Complexity: O(n) 61 | Space Complexity: O(n) 62 | */ -------------------------------------------------------------------------------- /Mixed/Medium/6. Sort the Matrix Diagonally.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/sort-the-matrix-diagonally/ 2 | 3 | class Solution { 4 | public: 5 | vector> diagonalSort(vector>& mat) { 6 | int n=mat.size(), m=mat[0].size(), diff=0; 7 | // 00, 11, 22 8 | // 10, 21 9 | // 20 10 | for(int i=0;i, greater> temp; 12 | for(int j=0;j=0 && j-diff=0 && j-diff, greater> temp; 33 | for(int i=0;i rob1(int i, bool first, vector& nums){ 6 | if((i==nums.size()-1 && first) || i==nums.size()){ 7 | return {0,0}; 8 | } 9 | auto exclude=rob1(i+1, first, nums); 10 | vector res(2, 0); 11 | // exclude 12 | res[0]=max(exclude[0], exclude[1]); 13 | // include 14 | res[1]=exclude[0]+nums[i]; 15 | return res; 16 | } 17 | public: 18 | int rob(vector& nums) { 19 | if(nums.size()==1) 20 | return nums[0]; 21 | // robbery starts from house 1 22 | vector r1=rob1(0, true, nums); 23 | // robbery starts from house 2 24 | vector r2=rob1(1, false, nums); 25 | return max({r1[0], r1[1], r2[0], r2[1]}); 26 | } 27 | }; 28 | 29 | // easy to understand 30 | class Solution { 31 | vector rob1_(int i, vector& nums){ 32 | if(i==nums.size()-1) 33 | return {0,0}; 34 | auto excl = rob1_(i+1, nums); 35 | vector res(2,0); 36 | res[0]=max(excl[0], excl[1]); // exclude 37 | res[1]=nums[i]+excl[0]; //include 38 | cout<"< rob2_(int i, vector& nums){ 42 | if(i==nums.size()) 43 | return {0,0}; 44 | auto excl = rob2_(i+1, nums); 45 | vector res(2,0); 46 | res[0]=max(excl[0], excl[1]); // exclude 47 | res[1]=nums[i]+excl[0]; //include 48 | cout<"<& nums) { 53 | if(nums.size()==1) 54 | return nums[0]; 55 | auto res1 = rob1_(0, nums); 56 | auto res2 = rob2_(1, nums); 57 | return max({res1[0], res1[1], res2[0], res2[1]}); 58 | } 59 | }; 60 | 61 | /* 62 | Time Complexity: O(n) 63 | Space Complexity: O(n) 64 | */ -------------------------------------------------------------------------------- /Mixed/Medium/8. PrefixSum - Shifting Letters II.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/shifting-letters-ii/ 2 | 3 | // prefix sum 4 | class Solution { 5 | public: 6 | string shiftingLetters(string S, vector>& shifts) { 7 | vector pre_sum(S.length()+1, 0); 8 | for(auto &s: shifts){ 9 | // populating prefix sum 10 | if(s[2]==1) 11 | pre_sum[s[0]]++, pre_sum[s[1]+1]--; 12 | else 13 | pre_sum[s[0]]--, pre_sum[s[1]+1]++; 14 | 15 | // handling negative here itself 16 | if(pre_sum[s[0]]<0) 17 | pre_sum[s[0]]=25; 18 | if(pre_sum[s[1]+1]<0) 19 | pre_sum[s[1]+1]=25; 20 | } 21 | int sum=0; 22 | for(int i=0;i>& shifts) { 44 | vector all_shifts(S.length(), 0); 45 | for(auto &s: shifts){ 46 | // this is time taking 47 | for(int i=s[0];i<=s[1];i++){ 48 | if(s[2]==1) 49 | all_shifts[i]++; 50 | else 51 | all_shifts[i]--; 52 | if(all_shifts[i]<0) 53 | all_shifts[i]=25; 54 | } 55 | } 56 | for(int i=0;i &ans, int &n){ 5 | // cout<>temp; 13 | ans.insert(temp); 14 | return; 15 | } 16 | char ch='0'+num; 17 | vec.push_back(ch); 18 | if(num-k>=0){ 19 | help(pos+1, num-k, k, vec, ans, n); 20 | } 21 | if(num+k<10){ 22 | help(pos+1, num+k, k, vec, ans, n); 23 | } 24 | } 25 | 26 | public: 27 | vector numsSameConsecDiff(int n, int k) { 28 | // dfs 29 | string vec; 30 | unordered_set ans; 31 | for(int i=1;i<10;i++) 32 | help(0, i, k, vec, ans, n); 33 | vector res; 34 | for(auto &a:ans) 35 | res.push_back(a); 36 | return res; 37 | } 38 | }; 39 | 40 | /* 41 | Time Complexity: O(2^n) 42 | Space Complexity: O(2^n) 43 | */ -------------------------------------------------------------------------------- /Mixed/Medium/Array - Product of Array Except Self.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/product-of-array-except-self/ 2 | 3 | class Solution { 4 | public: 5 | vector productExceptSelf(vector& nums) { 6 | // right and left products - without extra space 7 | int n=nums.size(); 8 | vector ans(n); 9 | 10 | // populate values in rigth and left 11 | int rightprod=1; 12 | for(int i=0;i=0;i--){ 18 | ans[i]=ans[i]*leftprod; 19 | leftprod*=nums[i]; 20 | } 21 | return ans; 22 | } 23 | }; 24 | 25 | /* 26 | Time: O(n) 27 | Space: O(1) 28 | */ 29 | 30 | class Solution { 31 | public: 32 | vector productExceptSelf(vector& nums) { 33 | // right and left products 34 | int n=nums.size(); 35 | vector right(n, 1), left(n, 1); 36 | 37 | // populate values in rigth and left 38 | int rightprod=1; 39 | for(int i=0;i=0;i--){ 45 | left[i]=leftprod; 46 | leftprod*=nums[i]; 47 | } 48 | 49 | vector ans(n); 50 | for(int i=0;i spiralOrder(vector>& matrix) { 6 | int n=matrix.size(), m=matrix[0].size(); 7 | int rightLim=0, upLim=0, leftLim=m-1, downLim=n-1; 8 | vector ans; 9 | 10 | while(rightLim<=leftLim && upLim<=downLim){ 11 | for(int i=rightLim; i<=leftLim; i++){ 12 | ans.push_back(matrix[upLim][i]); 13 | } 14 | upLim++; 15 | if(ans.size()==m*n) 16 | break; 17 | for(int i=upLim; i<=downLim; i++){ 18 | ans.push_back(matrix[i][leftLim]); 19 | } 20 | if(ans.size()==m*n) 21 | break; 22 | leftLim--; 23 | for(int i=leftLim; i>=rightLim; i--){ 24 | ans.push_back(matrix[downLim][i]); 25 | } 26 | if(ans.size()==m*n) 27 | break; 28 | downLim--; 29 | for(int i=downLim; i>=upLim; i--){ 30 | ans.push_back(matrix[i][rightLim]); 31 | } 32 | if(ans.size()==m*n) 33 | break; 34 | rightLim++; 35 | } 36 | 37 | return ans; 38 | } 39 | }; 40 | 41 | /* 42 | Time: O(n*m) 43 | Extra Space: O(1) 44 | */ -------------------------------------------------------------------------------- /Mixed/Medium/Minimum Operations to Make Array Equal II.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/contest/biweekly-contest-96/problems/minimum-operations-to-make-array-equal-ii/ 2 | 3 | class Solution { 4 | public: 5 | long long minOperations(vector& nums1, vector& nums2, int k) { 6 | long long inc=0, dec=0; 7 | 8 | for(int i=0; inums2[i]){ 18 | dec+=(diff/k); 19 | // nums1[i]=nums1[i]-diff=nums2[i] 20 | } 21 | else{ 22 | inc+=(diff/k); 23 | // nums1[i]=nums1[i]+diff=nums2[i] 24 | } 25 | } 26 | return inc==dec?inc:-1; 27 | } 28 | }; 29 | 30 | /* 31 | Time: O(n) 32 | Space: O(1) 33 | */ -------------------------------------------------------------------------------- /Mixed/Medium/Stack & string - Evaluate Reverse Polish Notation.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/evaluate-reverse-polish-notation/ 2 | 3 | class Solution { 4 | public: 5 | int evalRPN(vector& tokens) { 6 | stack st; 7 | int ans=-1; 8 | for(string s: tokens){ 9 | if(s=="+" || s=="-" || s=="*" || s=="/"){ 10 | long t1=st.top(); 11 | st.pop(); 12 | long t2=st.top(); 13 | st.pop(); 14 | long t; 15 | if(s=="+") t=t2+t1; 16 | else if(s=="-") t=t2-t1; 17 | else if(s=="/") t=t2/t1; 18 | else if(s=="*") t=t2*t1; 19 | // cout<>temp; 27 | // cout<& s, int pos=0) { 6 | if(pos==s.size()/2) 7 | return; 8 | swap(s[pos], s[s.size()-pos-1]); 9 | reverseString(s, pos+1); 10 | } 11 | }; -------------------------------------------------------------------------------- /Recursion/10. Recursion - Find the Winner of the Circular Game.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/find-the-winner-of-the-circular-game/ 2 | 3 | class Solution { 4 | int help(int n, int &k) { 5 | if(n==1){ 6 | return 0; 7 | } 8 | return ((help(n-1, k)+k)%n); 9 | } 10 | public: 11 | int findTheWinner(int n, int k) { 12 | return help(n, k) +1; 13 | } 14 | }; -------------------------------------------------------------------------------- /Recursion/11. Recursion - Maximum Length of a Concatenated String with Unique Characters.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/maximum-length-of-a-concatenated-string-with-unique-characters/submissions/ 2 | 3 | class Solution { 4 | bool compare(vector selected, string currString) { 5 | vector selfCheck(26, 0); // checks whether the string is valid in itself, eg. "cerc" or "eccr" are not valid because of repeated c's 6 | for(int i=0;i &arr, vector selected, int len) { 21 | // base condition 22 | if(i==arr.size()){ 23 | return len; 24 | } 25 | 26 | string currString = arr[i]; // i'th string in arr 27 | if(compare(selected, currString)==false) { 28 | // that means we cannot merge or concatenate this string with the group of strings merged so far 29 | // so simply skip this string 30 | return help(i+1, arr, selected, len); 31 | } 32 | else { 33 | // no conflicts => either pick or skip, handle both cases for getting required max length 34 | // if we skip, it's the same as the if case above 35 | int op1 = help(i+1, arr, selected, len); 36 | 37 | // if we pick 38 | for(int j=0;j& arr) { 48 | vector selected(26, false); // initialized for helper 49 | return help(0, arr, selected, 0); 50 | } 51 | }; -------------------------------------------------------------------------------- /Recursion/12. Recursion - Partition to K Equal Sum Subsets.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/partition-to-k-equal-sum-subsets/ 2 | 3 | // gives TLE on large test cases as DP is required for the optimized solution 4 | 5 | class Solution { 6 | bool help(int i, int bucketSum, int bucketNum, vector picked, vector& nums, int &requiredSum, int &K){ 7 | // base condition 8 | if(bucketNum==K){ 9 | return true; 10 | } 11 | if(bucketSum==requiredSum){ 12 | return help(0, 0, bucketNum+1, picked, nums, requiredSum, K); 13 | } 14 | else if(bucketSum>requiredSum){ 15 | return false; 16 | } 17 | if(i>=nums.size()) 18 | return false; 19 | 20 | if(picked[i]){ 21 | // skip 22 | return help(i+1, bucketSum, bucketNum, picked, nums, requiredSum, K); 23 | } 24 | else{ 25 | // skip 26 | bool op1 = help(i+1, bucketSum, bucketNum, picked, nums, requiredSum, K); 27 | // pick 28 | picked[i]=1; 29 | bucketSum+=nums[i]; 30 | bool op2 = help(i+1, bucketSum, bucketNum, picked, nums, requiredSum, K); 31 | return op1 | op2; 32 | } 33 | } 34 | public: 35 | bool canPartitionKSubsets(vector& nums, int k) { 36 | // Write your code here. 37 | int n=nums.size(); 38 | vector picked(n, false); 39 | int requiredSum=accumulate(nums.begin(), nums.end(), 0); 40 | if(requiredSum%k) 41 | return false; 42 | else requiredSum/=k; 43 | return help(0, 0, 0, picked, nums, requiredSum, k); 44 | } 45 | }; -------------------------------------------------------------------------------- /Recursion/13. Recursion - Flood Fill.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/flood-fill/ 2 | 3 | class Solution { 4 | int dx[4]={-1, 0, 0, 1}, dy[4]={0, -1, 1, 0}; 5 | 6 | void help(vector> &vis, vector> &image, int &m, int &n, int x, int y, int &oldColor, int newColor) { 7 | if(x<0 || x>=n || y<0 || y>=m || vis[x][y] || image[x][y]!=oldColor){ 8 | return; 9 | } 10 | vis[x][y]=true; 11 | image[x][y]=newColor; 12 | for(int k=0;k<4;k++){ 13 | help(vis, image, m, n, x+dx[k], y+dy[k], oldColor, newColor); 14 | } 15 | } 16 | public: 17 | vector> floodFill(vector>& image, int x, int y, int newColor) { 18 | int n=image.size(), m=image[0].size(); 19 | vector> vis(n, vector (m, false)); 20 | int oldColor=image[x][y]; 21 | help(vis, image, m, n, x, y, oldColor, newColor); 22 | return image; 23 | } 24 | }; -------------------------------------------------------------------------------- /Recursion/14. Recursion - Rat In A Maze.cpp: -------------------------------------------------------------------------------- 1 | // https://www.codingninjas.com/codestudio/problems/rat-in-a-maze_1215030 2 | 3 | int dx[4]={1, 0, 0, -1}, dy[4]={0, -1, 1, 0}; 4 | char d[4]={'D', 'L', 'R', 'U'}; 5 | 6 | void help(int i, int j, int &n, vector < vector < int >> & arr, string path, vector &ans) { 7 | if(i<0 || j<0 || i==n || j==n || arr[i][j]==0) { 8 | return; 9 | } 10 | else if(i==n-1 && j==n-1) { 11 | ans.push_back(path); 12 | return; 13 | } 14 | else{ 15 | arr[i][j]=0; 16 | // lexicographical => DLRU 17 | for(int k=0;k<4;k++){ 18 | path.push_back(d[k]); 19 | help(i+dx[k], j+dy[k], n, arr, path, ans); 20 | path.pop_back(); 21 | } 22 | arr[i][j]=1; 23 | } 24 | } 25 | vector < string > searchMaze(vector < vector < int >> & arr, int n) { 26 | // Write your code here. 27 | vector ans; 28 | string path; 29 | help(0, 0, n, arr, path, ans); 30 | return ans; 31 | } -------------------------------------------------------------------------------- /Recursion/2. Recursion - Reverse Linked List.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/reverse-linked-list/ 2 | 3 | class Solution { 4 | ListNode* ans=NULL; 5 | void helper(ListNode* head, ListNode* prev){ 6 | if(!head){ 7 | ans=prev; 8 | return; 9 | } 10 | ListNode* temp=head->next; 11 | head->next=prev; 12 | prev=head; 13 | head=temp; 14 | helper(head, prev); 15 | } 16 | 17 | public: 18 | ListNode* reverseList(ListNode* head) { 19 | helper(head, NULL); 20 | return ans; 21 | } 22 | }; -------------------------------------------------------------------------------- /Recursion/3. Recursion - Fibonacci Number.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/fibonacci-number/submissions/ 2 | 3 | class Solution { 4 | vector dp=vector(31, -1); 5 | public: 6 | int fib(int n) { 7 | if(dp[n]!=-1) return dp[n]; 8 | if(n<2) return dp[n]=n; 9 | return dp[n]=fib(n-1)+fib(n-2); 10 | } 11 | }; -------------------------------------------------------------------------------- /Recursion/4. Recursion - Merge Two Sorted Lists.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/merge-two-sorted-lists/submissions/ 2 | 3 | class Solution { 4 | void helper(ListNode* ptr, ListNode* list1, ListNode* list2) { 5 | if(!list1 && !list2) 6 | return; 7 | if(!list1){ 8 | ptr->next=list2; 9 | } 10 | else if(!list2){ 11 | ptr->next=list1; 12 | } 13 | else if(list1->valval){ 14 | ptr->next=list1; 15 | helper(ptr->next, list1->next, list2); 16 | } 17 | else{ 18 | ptr->next=list2; 19 | helper(ptr->next, list1, list2->next); 20 | } 21 | } 22 | public: 23 | ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) { 24 | ListNode* ptr=new ListNode(0); 25 | helper(ptr, list1, list2); 26 | return ptr->next; 27 | } 28 | }; -------------------------------------------------------------------------------- /Recursion/5. Recursion - Palindrome Linked List.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/palindrome-linked-list/submissions/ 2 | 3 | class Solution { 4 | ListNode* start; 5 | bool helper(ListNode* end){ 6 | if(!end) 7 | return true; 8 | if(!helper(end->next)) 9 | return false; 10 | if(start->val!=end->val) 11 | return false; 12 | start=start->next; 13 | return true; 14 | } 15 | public: 16 | bool isPalindrome(ListNode* head) { 17 | if(!head || !head->next) return true; 18 | ListNode* end=head; 19 | start=head; 20 | return helper(end); 21 | } 22 | }; -------------------------------------------------------------------------------- /Recursion/6. Recursion - Power of Two.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/power-of-two/submissions/ 2 | 3 | class Solution { 4 | public: 5 | bool isPowerOfTwo(int n) { 6 | if(n==1) 7 | return true; 8 | if(n==0 || n%2) 9 | return false; 10 | return isPowerOfTwo(n/2); 11 | } 12 | }; -------------------------------------------------------------------------------- /Recursion/7. Recursion - Power of Four.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/power-of-four/ 2 | 3 | class Solution { 4 | public: 5 | bool isPowerOfFour(int n) { 6 | if(n==1) 7 | return true; 8 | if(n==0 || n%4) 9 | return false; 10 | return isPowerOfFour(n/4); 11 | } 12 | }; -------------------------------------------------------------------------------- /Recursion/8. Recursion - Remove Linked List Elements.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/remove-linked-list-elements/submissions/ 2 | 3 | class Solution { 4 | void help(ListNode* temp, ListNode* head, int &val){ 5 | if(!head){ 6 | temp->next=NULL; 7 | return; 8 | } 9 | if(head->val!=val){ 10 | temp->next=head; 11 | help(temp->next, head->next, val); 12 | } 13 | else{ 14 | help(temp, head->next, val); 15 | } 16 | 17 | } 18 | public: 19 | ListNode* removeElements(ListNode* head, int val) { 20 | ListNode* temp=new ListNode(0); 21 | temp->next=head; 22 | auto temp2=temp; 23 | help(temp2, head, val); 24 | return temp->next; 25 | } 26 | }; -------------------------------------------------------------------------------- /Recursion/9. Recursion - Power of Three.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/power-of-three/ 2 | 3 | class Solution { 4 | public: 5 | bool isPowerOfThree(int n) { 6 | if(n==1) 7 | return true; 8 | if(n==0 || n%3) 9 | return false; 10 | return isPowerOfThree(n/3); 11 | } 12 | }; -------------------------------------------------------------------------------- /Sliding Window/Sliding Window Maximum.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/sliding-window-maximum/ 2 | 3 | // we can also solve it using deque 4 | 5 | class Solution { 6 | public: 7 | vector maxSlidingWindow(vector& nums, int k) { 8 | int n=nums.size(); 9 | 10 | // base case 11 | if(n<=k){ 12 | int max_=nums[0]; 13 | for(int i=1;i ans; 19 | priority_queue> pq; 20 | 21 | // first iteration 22 | for(int i=0;i &quiet, unordered_map> &graph, vector &ans) { 5 | if(ans[i]!=-1) 6 | return; 7 | int least_quiet=i; 8 | 9 | for(int &nbr: graph[i]) { 10 | if(ans[nbr]==-1) dfs(nbr, quiet, graph, ans); 11 | if(quiet[ans[nbr]]loudAndRich(vector>& richer, vector& quiet) { 18 | unordered_map> graph; 19 | int n=quiet.size(); 20 | vector ans(n, -1); 21 | 22 | for(int i=0; i> graph; 9 | vector inDeg(K, 0); 10 | for(int i=1;i q; 23 | string ans; 24 | // now we have the graph, performing topological sort on the same 25 | for(int i=0;i &ans, bool &isCyclic, vector &bag, vector &vis, int &n, vector> &graph){ 5 | if(isCyclic) 6 | return; 7 | vis[i]=1; 8 | bag[i]=1; 9 | for(int &nbr: graph[i]){ 10 | if(!vis[nbr]){ 11 | topoSort(nbr, ans, isCyclic, bag, vis, n, graph); 12 | } 13 | else if(bag[nbr]){ 14 | isCyclic=true; 15 | return; 16 | } 17 | } 18 | bag[i]=0; 19 | ans.push_back(i); 20 | } 21 | public: 22 | vector findOrder(int numCourses, vector>& prerequisites) { 23 | vector> graph(numCourses); 24 | for(vector &pre: prerequisites){ 25 | graph[pre[0]].push_back(pre[1]); 26 | } 27 | // cycle detection should also be there 28 | 29 | vector vis(numCourses, false); 30 | vector ans; 31 | for(int i=0;i bag(numCourses, false); 34 | bool isCyclic=false; 35 | topoSort(i, ans, isCyclic, bag, vis, numCourses, graph); 36 | if(isCyclic) 37 | return {}; 38 | } 39 | } 40 | return ans; 41 | } 42 | }; 43 | 44 | /* 45 | Time: O(n+v) 46 | Space: O(n+v) 47 | */ -------------------------------------------------------------------------------- /Topological Sort/Course Schedule.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/course-schedule/ 2 | 3 | class Solution { 4 | public: 5 | bool canFinish(int numCourses, vector>& prerequisites) { 6 | map> graph; 7 | vector indeg(numCourses, 0); 8 | 9 | for(auto &pre: prerequisites){ 10 | graph[pre[1]].push_back(pre[0]); 11 | indeg[pre[0]]++; 12 | } 13 | 14 | queue q; 15 | vector completed(numCourses, false); 16 | 17 | for(int i=0; i findMinHeightTrees(int n, vector>& edges) { 6 | if(n==1) 7 | return {0}; 8 | map> graph; 9 | 10 | // we are building inverted tree -> decide the leaves first 11 | for(auto &e: edges){ 12 | graph[e[0]].insert(e[1]); 13 | graph[e[1]].insert(e[0]); 14 | } 15 | 16 | queue q; 17 | for(auto &e: graph){ 18 | if(e.second.size()==1) 19 | q.push(e.first); 20 | } 21 | 22 | while(!q.empty()){ 23 | int s=q.size(); 24 | if(n<=2) 25 | break; 26 | while(s--){ 27 | int f=q.front(); 28 | q.pop(); 29 | n--; 30 | for(int nbr: graph[f]){ 31 | graph[nbr].erase(f); 32 | if(graph[nbr].size()==1) 33 | q.push(nbr); 34 | } 35 | } 36 | } 37 | 38 | // tree was constructed leaves to root 39 | vector ans; 40 | while(!q.empty()){ 41 | ans.push_back(q.front()); 42 | q.pop(); 43 | } 44 | 45 | return ans; 46 | } 47 | }; 48 | 49 | /* 50 | Time: O(n+v) 51 | Space: O(n+v) 52 | */ -------------------------------------------------------------------------------- /Topological Sort/White-Gray-Black - Find Eventual Safe States.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/find-eventual-safe-states/ 2 | 3 | class Solution { 4 | bool dfs(int i, vector &color, vector>& graph) { 5 | if(color[i]) 6 | return color[i]==2; 7 | color[i]=1; 8 | for(int &nbr: graph[i]){ 9 | if(color[nbr]==2) // safe 10 | continue; 11 | if(color[nbr]==1 || dfs(nbr, color, graph)==false) 12 | return false; 13 | } 14 | color[i]=2; 15 | return true; 16 | } 17 | public: 18 | vector eventualSafeNodes(vector>& graph) { 19 | int n=graph.size(); 20 | vector ans; 21 | // white-gray-black dfs 22 | vector color(n, 0); 23 | // white=0, gray=1, black=2 24 | for(int i=0;ileft) maxDepth(root->left, tempAns+1, ans); 19 | if(root->right) maxDepth(root->right, tempAns+1, ans); 20 | } 21 | public: 22 | int maxDepth(TreeNode* root) { 23 | if(!root) return 0; 24 | int ans = 1; 25 | maxDepth(root, 1, ans); 26 | return ans; 27 | } 28 | }; -------------------------------------------------------------------------------- /Tree/10. N-ary Tree Preorder Traversal.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/n-ary-tree-preorder-traversal/ 2 | 3 | /* 4 | // Definition for a Node. 5 | class Node { 6 | public: 7 | int val; 8 | vector children; 9 | 10 | Node() {} 11 | 12 | Node(int _val) { 13 | val = _val; 14 | } 15 | 16 | Node(int _val, vector _children) { 17 | val = _val; 18 | children = _children; 19 | } 20 | }; 21 | */ 22 | 23 | class Solution { 24 | public: 25 | vector preorder(Node* root) { 26 | vector ans; 27 | if(!root) 28 | return ans; 29 | stack st; 30 | st.push(root); 31 | while(!st.empty()){ 32 | auto top=st.top(); 33 | st.pop(); 34 | ans.push_back(top->val); 35 | for(int i=top->children.size()-1;i>=0;i--){ 36 | auto ch = top->children[i]; 37 | st.push(ch); 38 | } 39 | } 40 | return ans; 41 | } 42 | }; 43 | 44 | /* 45 | Time: O(n) 46 | Space: O(n) 47 | */ -------------------------------------------------------------------------------- /Tree/11. Binary Tree Level Order Traversal.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/binary-tree-level-order-traversal/ 2 | 3 | /** 4 | * Definition for a binary tree node. 5 | * struct TreeNode { 6 | * int val; 7 | * TreeNode *left; 8 | * TreeNode *right; 9 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 10 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 12 | * }; 13 | */ 14 | class Solution { 15 | public: 16 | vector> levelOrder(TreeNode* root) { 17 | vector> ans; 18 | if(!root) return ans; 19 | queue q; 20 | q.push(root); 21 | while(!q.empty()) { 22 | vector lvl; 23 | int s=q.size(); 24 | while(s--){ 25 | auto top=q.front(); 26 | q.pop(); 27 | lvl.push_back(top->val); 28 | if(top->left){ 29 | q.push(top->left); 30 | } 31 | if(top->right){ 32 | q.push(top->right); 33 | } 34 | } 35 | ans.push_back(lvl); 36 | } 37 | return ans; 38 | } 39 | }; 40 | 41 | /* 42 | Time: O(n) 43 | Space: O(n) 44 | */ -------------------------------------------------------------------------------- /Tree/11. Binary Tree Pruning.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/binary-tree-pruning/ 2 | 3 | /** 4 | * Definition for a binary tree node. 5 | * struct TreeNode { 6 | * int val; 7 | * TreeNode *left; 8 | * TreeNode *right; 9 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 10 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 12 | * }; 13 | */ 14 | class Solution { 15 | bool help(TreeNode* root){ 16 | if(!root) 17 | return false; 18 | bool ansR=false, ansL=false; 19 | if(help(root->left)){ 20 | root->left=NULL; 21 | ansL=true; 22 | } 23 | if(help(root->right)){ 24 | root->right=NULL; 25 | ansR=true; 26 | } 27 | if(root->left==NULL && root->right==NULL){ 28 | return root->val==0?true:false; 29 | } 30 | return ansL&&ansR; 31 | } 32 | public: 33 | TreeNode* pruneTree(TreeNode* root) { 34 | help(root); 35 | if(root->val==0 && root->left ==NULL && root->right==NULL) 36 | return NULL; 37 | return root; 38 | } 39 | }; 40 | 41 | /* 42 | Time Complexity: O(n) 43 | Space Complexity: O(n) 44 | */ -------------------------------------------------------------------------------- /Tree/12. N-ary Tree Level Order Traversal.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/n-ary-tree-level-order-traversal/ 2 | 3 | /* 4 | // Definition for a Node. 5 | class Node { 6 | public: 7 | int val; 8 | vector children; 9 | 10 | Node() {} 11 | 12 | Node(int _val) { 13 | val = _val; 14 | } 15 | 16 | Node(int _val, vector _children) { 17 | val = _val; 18 | children = _children; 19 | } 20 | }; 21 | */ 22 | 23 | class Solution { 24 | public: 25 | vector> levelOrder(Node* root) { 26 | vector> ans; 27 | if(!root) return ans; 28 | queue q; 29 | q.push(root); 30 | while(!q.empty()) { 31 | vector lvl; 32 | int s=q.size(); 33 | while(s--){ 34 | auto top=q.front(); 35 | q.pop(); 36 | lvl.push_back(top->val); 37 | for(auto ch:top->children) 38 | q.push(ch); 39 | } 40 | ans.push_back(lvl); 41 | } 42 | return ans; 43 | } 44 | }; 45 | 46 | /* 47 | Time: O(n) 48 | Space: O(n) 49 | */ -------------------------------------------------------------------------------- /Tree/13. Vertical Order Traversal of a Binary Tree.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/vertical-order-traversal-of-a-binary-tree/ 2 | 3 | /** 4 | * Definition for a binary tree node. 5 | * struct TreeNode { 6 | * int val; 7 | * TreeNode *left; 8 | * TreeNode *right; 9 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 10 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 12 | * }; 13 | */ 14 | class Solution { 15 | void getOrder(TreeNode* root, int lvl, int depth, map>> &mp) { 16 | if(!root) 17 | return; 18 | mp[lvl].push_back({depth, root->val}); 19 | getOrder(root->left, lvl-1, depth+1, mp); 20 | getOrder(root->right, lvl+1, depth+1, mp); 21 | } 22 | public: 23 | vector> verticalTraversal(TreeNode* root) { 24 | vector> ans; 25 | if(!root) return ans; 26 | map>> mp; 27 | getOrder(root, 0, 0, mp); 28 | int s=mp.size(); 29 | for(auto &a: mp){ 30 | sort(a.second.begin(), a.second.end()); 31 | } 32 | for(auto &a:mp){ 33 | vector temp; 34 | for(auto b: a.second){ 35 | temp.push_back(b[1]); 36 | } 37 | ans.push_back(temp); 38 | } 39 | return ans; 40 | } 41 | }; 42 | 43 | /* 44 | Time complexity: 45 | getOrder -> O(n), n is the no. of nodes in the tree 46 | map travelsal & sorting -> O(h*nlogn), h is the height of the tree 47 | => O(h*nlogn) 48 | Space complexity: O(n) 49 | */ -------------------------------------------------------------------------------- /Tree/14. Diagonal Traversal of Binary Tree.cpp: -------------------------------------------------------------------------------- 1 | // https://practice.geeksforgeeks.org/problems/diagonal-traversal-of-binary-tree/1 2 | 3 | /* A binary tree node 4 | struct Node 5 | { 6 | int data; 7 | Node* left, * right; 8 | }; */ 9 | 10 | void dfs(map> &mp, int diagLvl, Node* root) 11 | { 12 | if(!root) 13 | return; 14 | mp[diagLvl].push_back(root->data); 15 | dfs(mp, diagLvl+1, root->left); 16 | dfs(mp, diagLvl, root->right); 17 | } 18 | 19 | vector diagonal(Node *root) 20 | { 21 | // your code here 22 | // dfs 23 | vector ans; 24 | map> mp; 25 | dfs(mp, 0, root); 26 | for(auto &a:mp){ 27 | for(auto &b: a.second){ 28 | ans.push_back(b); 29 | } 30 | } 31 | return ans; 32 | } 33 | 34 | /* 35 | Time Complexity: O(n) 36 | Space Complexity: O(n) 37 | */ -------------------------------------------------------------------------------- /Tree/2. Minimum Depth of Binary Tree.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/minimum-depth-of-binary-tree/ 2 | 3 | /** 4 | * Definition for a binary tree node. 5 | * struct TreeNode { 6 | * int val; 7 | * TreeNode *left; 8 | * TreeNode *right; 9 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 10 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 12 | * }; 13 | */ 14 | class Solution { 15 | void minDepth(TreeNode* root, int tempAns, int &ans) { 16 | if(!root) return; 17 | if(!root->left && !root->right) 18 | ans=min(ans, tempAns); 19 | if(root->left) minDepth(root->left, tempAns+1, ans); 20 | if(root->right) minDepth(root->right, tempAns+1, ans); 21 | } 22 | public: 23 | int minDepth(TreeNode* root) { 24 | if(!root) return 0; 25 | int ans = INT_MAX; 26 | minDepth(root, 1, ans); 27 | return ans; 28 | } 29 | }; -------------------------------------------------------------------------------- /Tree/3. Balanced Binary Tree.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/balanced-binary-tree/ 2 | 3 | /** 4 | * Definition for a binary tree node. 5 | * struct TreeNode { 6 | * int val; 7 | * TreeNode *left; 8 | * TreeNode *right; 9 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 10 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 12 | * }; 13 | */ 14 | class Solution { 15 | int height(TreeNode* root) { 16 | if(!root) return 0; 17 | return 1+max(height(root->left), height(root->right)); 18 | } 19 | public: 20 | bool isBalanced(TreeNode* root) { 21 | if(!root) return true; 22 | int leftHeight = height(root->left); 23 | int rightHeight = height(root->right); 24 | return abs(leftHeight-rightHeight)<=1 && isBalanced(root->left) && isBalanced(root->right); 25 | } 26 | }; -------------------------------------------------------------------------------- /Tree/4. Maximum Depth of N-ary Tree.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/maximum-depth-of-n-ary-tree/ 2 | 3 | /* 4 | // Definition for a Node. 5 | class Node { 6 | public: 7 | int val; 8 | vector children; 9 | 10 | Node() {} 11 | 12 | Node(int _val) { 13 | val = _val; 14 | } 15 | 16 | Node(int _val, vector _children) { 17 | val = _val; 18 | children = _children; 19 | } 20 | }; 21 | */ 22 | 23 | class Solution { 24 | void maxDepth(Node* root, int tempAns, int &ans) { 25 | if(!root) return; 26 | ans=max(ans, tempAns); 27 | 28 | for(auto ch:root->children) 29 | if(ch) maxDepth(ch, tempAns+1, ans); 30 | } 31 | public: 32 | int maxDepth(Node* root) { 33 | if(!root) return 0; 34 | int ans = 1; 35 | maxDepth(root, 1, ans); 36 | return ans; 37 | } 38 | }; -------------------------------------------------------------------------------- /Tree/5. Same Tree.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/same-tree/ 2 | 3 | /** 4 | * Definition for a binary tree node. 5 | * struct TreeNode { 6 | * int val; 7 | * TreeNode *left; 8 | * TreeNode *right; 9 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 10 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 12 | * }; 13 | */ 14 | class Solution { 15 | public: 16 | bool isSameTree(TreeNode* p, TreeNode* q) { 17 | if(!p && !q) return true; 18 | if(!p || !q) return false; 19 | if(p->val!=q->val) return false; 20 | return (isSameTree(p->left, q->left)&&isSameTree(p->right, q->right)); 21 | } 22 | }; -------------------------------------------------------------------------------- /Tree/6. Diameter of Binary Tree.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/diameter-of-binary-tree/ 2 | 3 | /** 4 | * Definition for a binary tree node. 5 | * struct TreeNode { 6 | * int val; 7 | * TreeNode *left; 8 | * TreeNode *right; 9 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 10 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 12 | * }; 13 | */ 14 | class Solution { 15 | int ans=0; 16 | int height(TreeNode* root) { 17 | if(!root) return 0; 18 | return 1+max(height(root->left), height(root->right)); 19 | } 20 | public: 21 | int diameterOfBinaryTree(TreeNode* root) { 22 | if(!root) return 0; 23 | diameterOfBinaryTree(root->left); 24 | diameterOfBinaryTree(root->right); 25 | int leftHeight = height(root->left); 26 | int rightHeight = height(root->right); 27 | ans=max(ans, leftHeight+rightHeight+1); 28 | return ans>0?ans-1:ans; 29 | } 30 | }; -------------------------------------------------------------------------------- /Tree/7. Find a Corresponding Node of a Binary Tree in a Clone of That Tree.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/find-a-corresponding-node-of-a-binary-tree-in-a-clone-of-that-tree/ 2 | 3 | /** 4 | * Definition for a binary tree node. 5 | * struct TreeNode { 6 | * int val; 7 | * TreeNode *left; 8 | * TreeNode *right; 9 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 10 | * }; 11 | */ 12 | 13 | class Solution { 14 | public: 15 | TreeNode* getTargetCopy(TreeNode* original, TreeNode* cloned, TreeNode* target) { 16 | if(!original) 17 | return NULL; 18 | if(original==target) 19 | return cloned; 20 | auto left = getTargetCopy(original->left, cloned->left, target); 21 | if(left) 22 | return left; 23 | auto right = getTargetCopy(original->right, cloned->right, target); 24 | if(right) 25 | return right; 26 | return NULL; 27 | } 28 | }; 29 | 30 | /* 31 | Time: O(n) 32 | Space: O(n) 33 | */ -------------------------------------------------------------------------------- /Tree/8. Binary Tree Preorder Traversal.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/binary-tree-preorder-traversal/ 2 | 3 | /** 4 | * Definition for a binary tree node. 5 | * struct TreeNode { 6 | * int val; 7 | * TreeNode *left; 8 | * TreeNode *right; 9 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 10 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 11 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 12 | * }; 13 | */ 14 | class Solution { 15 | void help(TreeNode* root, vector &ans) { 16 | if(!root) return; 17 | ans.push_back(root->val); 18 | help(root->left, ans); 19 | help(root->right, ans); 20 | } 21 | public: 22 | vector preorderTraversal(TreeNode* root) { 23 | vector ans; 24 | help(root, ans); 25 | return ans; 26 | } 27 | }; 28 | 29 | /* 30 | Time: O(n) 31 | Space: O(n) 32 | */ -------------------------------------------------------------------------------- /Tree/9. N-ary Tree Postorder Traversal.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/n-ary-tree-postorder-traversal/ 2 | 3 | /* 4 | // Definition for a Node. 5 | class Node { 6 | public: 7 | int val; 8 | vector children; 9 | 10 | Node() {} 11 | 12 | Node(int _val) { 13 | val = _val; 14 | } 15 | 16 | Node(int _val, vector _children) { 17 | val = _val; 18 | children = _children; 19 | } 20 | }; 21 | */ 22 | 23 | class Solution { 24 | void help(Node* root, vector &ans) { 25 | if(!root) return; 26 | if(root->children.size()) 27 | for(auto ch:root->children) 28 | help(ch, ans); 29 | ans.push_back(root->val); 30 | } 31 | public: 32 | vector postorder(Node* root) { 33 | vector ans; 34 | help(root, ans); 35 | return ans; 36 | } 37 | }; 38 | 39 | /* 40 | Time: O(n) 41 | Space: O(n) 42 | where n = no of nodes 43 | */ -------------------------------------------------------------------------------- /Trie/6. Trie.cpp: -------------------------------------------------------------------------------- 1 | // TRIE 2 | 3 | class Node { 4 | public: 5 | string data; 6 | unordered_map children; 7 | bool isTerminal; 8 | 9 | Node(string &val) { 10 | data=val; 11 | isTerminal=false; 12 | } 13 | }; 14 | 15 | class Trie { 16 | Node* root; 17 | 18 | public: 19 | Trie() { 20 | root=new Node("\0"); 21 | } 22 | 23 | void insert(string &word) { 24 | Node* temp=root; 25 | 26 | for (char &ch: word) { 27 | if (temp - > children.count(s)==0) { 28 | Node * n=new Node(s); 29 | temp ->children[s]=n; 30 | } 31 | 32 | temp=temp ->children[s]; 33 | } 34 | 35 | temp ->isTerminal=true; 36 | } 37 | 38 | bool search(string &word) { 39 | Node* temp=root; 40 | 41 | for (char &ch: word) { 42 | if (temp - > children.count(s)==0) { 43 | return false; 44 | } 45 | 46 | temp=temp ->children[s]; 47 | } 48 | 49 | temp ->isTerminal=true; 50 | } 51 | }; -------------------------------------------------------------------------------- /Trie/Phone directory.cpp: -------------------------------------------------------------------------------- 1 | // https://practice.geeksforgeeks.org/problems/phone-directory4628/1 2 | 3 | class Node{ 4 | public: 5 | char c; 6 | int count=0; 7 | set words; 8 | map children; 9 | Node(char &c){ 10 | this->c=c; 11 | } 12 | }; 13 | 14 | class Trie{ 15 | public: 16 | Node* root; 17 | Trie(char c){ 18 | root=new Node(c); 19 | } 20 | void insert(string &s){ 21 | Node* temp=root; 22 | for(char &c: s){ 23 | if(temp->children.count(c)==0){ 24 | temp->children[c]=new Node(c); 25 | } 26 | temp=temp->children[c]; 27 | temp->count++; 28 | temp->words.insert(s); 29 | } 30 | } 31 | }; 32 | 33 | class Solution{ 34 | public: 35 | vector> displayContacts(int N, string contact[], string s) 36 | { 37 | // code here 38 | Trie* trie=new Trie('\0'); 39 | for(int i=0;iinsert(contact[i]); 41 | } 42 | 43 | vector> ans; 44 | Node* temp=trie->root; 45 | int i=0, n=s.length(); 46 | for(i=0;ichildren.count(s[i])==0){ 48 | break; 49 | } 50 | temp=temp->children[s[i]]; 51 | vector v; 52 | for(string word:temp->words) 53 | v.push_back(word); 54 | ans.push_back(v); 55 | } 56 | while(i++ children; 7 | vector words; 8 | Node(char c){ 9 | ch=c; 10 | } 11 | }; 12 | 13 | class Trie{ 14 | public: 15 | Node* root; 16 | Trie(){ 17 | root=new Node('\0'); 18 | } 19 | void insert(string s){ 20 | Node* temp; 21 | temp=root; 22 | for(char c:s){ 23 | if(temp->children.count(c)==0) 24 | temp->children[c]=new Node(c); 25 | temp=temp->children[c]; 26 | temp->words.push_back(s); 27 | sort(temp->words.begin(), temp->words.end()); 28 | if(temp->words.size()==4) 29 | temp->words.pop_back(); 30 | } 31 | } 32 | }; 33 | 34 | class Solution { 35 | public: 36 | vector> suggestedProducts(vector& products, string searchWord) { 37 | Trie* trie=new Trie; 38 | for(string &p: products) 39 | trie->insert(p); 40 | vector> ans; 41 | Node* temp=trie->root; 42 | for(char c: searchWord){ 43 | if(temp->children.count(c)){ 44 | temp=temp->children[c]; 45 | ans.push_back(temp->words); 46 | } 47 | else 48 | break; 49 | } 50 | int n=ans.size(); 51 | while(n ch; 9 | bool eow; 10 | Node(char val){ 11 | this->val=val; 12 | eow=false; 13 | } 14 | }; 15 | class Trie { 16 | public: 17 | Node* root; 18 | Trie(){ 19 | root=new Node('\0'); 20 | } 21 | void insert(string &s){ 22 | Node* temp=root; 23 | for(auto &c: s){ 24 | if(temp->ch.count(c)==0) 25 | temp->ch[c]=new Node(c); 26 | temp=temp->ch[c]; 27 | } 28 | temp->eow=true; 29 | } 30 | }; 31 | set words; 32 | int dx[8]={0, 0, -1, -1, -1, 1, 1, 1}, dy[8]={1, -1, 0, -1, 1, 0, -1, 1}; 33 | void dfs(int i, int j, string s, Node *root, vector >& board, int &m, int &n) { 34 | // for backtracking 35 | char c=board[i][j]; 36 | board[i][j]='#'; 37 | 38 | if(root->eow){ 39 | root->eow=false; 40 | // don't break, this might be a suffix to another word 41 | words.insert(s); 42 | } 43 | 44 | for(int k=0;k<8;k++){ 45 | int nx=dx[k]+i, ny=dy[k]+j; 46 | if(nx>=0 && ny>=0 && nxch.count(board[nx][ny])){ 47 | dfs(nx, ny, s+board[nx][ny], root->ch[board[nx][ny]], board, m, n); 48 | } 49 | } 50 | 51 | board[i][j]=c; 52 | } 53 | public: 54 | vector wordBoggle(vector >& board, vector& dictionary) { 55 | // Code here 56 | Trie *trie=new Trie(); 57 | vector ans; 58 | int n=board.size(), m=board[0].size(); 59 | for(auto &s: dictionary){ 60 | trie->insert(s); 61 | } 62 | 63 | for(int i=0;iroot->ch.count(board[i][j])){ 66 | string s; 67 | s+=board[i][j]; 68 | dfs(i, j, s, trie->root->ch[board[i][j]], board, m, n); 69 | } 70 | } 71 | } 72 | for(auto &w: words) 73 | ans.push_back(w); 74 | return ans; 75 | } 76 | }; 77 | 78 | /* 79 | Time: O(n*m*(8^k)) 80 | Space: O(l*k), where i is the no. of words i dict and k is the max length of a word in the dict 81 | */ 82 | 83 | /* 84 | Input: 85 | N = 4 86 | dictionary = {"GEEKS","FOR","QUIZ","GO"} 87 | R = 3, C = 3 88 | board = {{G,I,Z},{U,E,K},{Q,S,E}} 89 | Output: 90 | GEEKS QUIZ 91 | */ -------------------------------------------------------------------------------- /Two Pointer/3. Two Pointer - Minimize Maximum Pair Sum in Array.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/minimize-maximum-pair-sum-in-array/ 2 | 3 | class Solution { 4 | public: 5 | int minPairSum(vector& nums) { 6 | auto v=nums; 7 | sort(v.begin(), v.end()); 8 | int n=v.size(); 9 | int ans=INT_MIN; 10 | for(int i=0;i partitionLabels(string s) { 6 | map mp; 7 | for(int i=0;i ans; 13 | 14 | while(i=j){ 18 | ans.push_back(siz); 19 | siz=0; 20 | } 21 | i++; 22 | } 23 | return ans; 24 | } 25 | }; 26 | 27 | /* 28 | Time: O(n) 29 | Space: O(n) 30 | */ -------------------------------------------------------------------------------- /Two Pointer/5. Two Pointer - Jump Game.cpp: -------------------------------------------------------------------------------- 1 | // https://leetcode.com/problems/jump-game 2 | 3 | class Solution { 4 | public: 5 | bool canJump(vector& nums) { 6 | // two pointer 7 | int i; 8 | // our first pointer 9 | int maxi=0; 10 | // our second pointer 11 | 12 | for(i=0;i0 ;i--){ 10 | if(s[i]>s[i-1]){ 11 | k=i-1; 12 | break; 13 | } 14 | } 15 | 16 | if(k!=-1){ 17 | // missed step 18 | for(int i=s.length()-1; i>k ;i--){ 19 | if(s[i]>s[k]){ 20 | swap(s[i], s[k]); 21 | break; 22 | } 23 | } 24 | sort(s.begin()+k+1, s.end()); 25 | } 26 | 27 | int n2=-1; 28 | try{ 29 | n2=stoi(s); 30 | } 31 | catch(...){ 32 | return -1; 33 | } 34 | return n2!=n?n2:-1; 35 | } 36 | }; 37 | 38 | /* 39 | l = no. of digits in n 40 | Time: O(llogl) 41 | Space: O(l) 42 | */ --------------------------------------------------------------------------------