├── 120. Triangle.md ├── 137. Single Number II.md ├── 1510. Stone Game IV.md ├── 1567. Maximum Length of Subarray With Positive Product.md ├── 1626. Best Team With No Conflicts.md ├── 1771. Maximize Palindrome Length From Subsequences.md ├── 1774. Closest Dessert Cost.md ├── 372. Super Pow.md ├── 399. Evaluate Division.md ├── 45. Jump Game II.md ├── 547. Number of Provinces.md ├── 576. Out of Boundary Paths.md ├── 765. Couples Holding Hands.md ├── 887. Super Egg Drop.md ├── All Buy and Sell Stock Problems.md ├── AmazonQuestionList ├── Google Questions.json ├── Google_L4_Screening.md ├── README.md ├── VisaQuestion └── [Premium]305. Number of islands-ii.md /120. Triangle.md: -------------------------------------------------------------------------------- 1 | 2 | **Here is three solution Recursive -> Memoization -> DP 3 | Step By Step.** 4 | 5 | **1.Recursive (It may give TLE , but good understanding of memoization and dp you should understand it first)** 6 | 7 | **42 / 43 test cases passed.** 8 | 9 | ``` 10 | class Solution { 11 | public: 12 | int minTotalUtil(vector>& triangle, int h, int j) { 13 | 14 | if(h == triangle.size()) { 15 | return 0; 16 | } 17 | 18 | return triangle[h][j]+min(minTotalUtil(triangle, h+1, j),minTotalUtil(triangle, h+1, j+1)); 19 | } 20 | int minimumTotal(vector>& triangle) { 21 | 22 | return minTotalUtil(triangle, 0, 0); 23 | } 24 | }; 25 | ``` 26 | 27 | **2. Memoization of recursive solution :** 28 | 29 | **Runtime: 12 ms 30 | Memory Usage: 8.9 MB** 31 | 32 | ``` 33 | class Solution { 34 | public: 35 | int minTotalUtil(vector>& triangle, int h, int j,vector> &v) { 36 | if(h == triangle.size()) { 37 | 38 | return 0; 39 | } 40 | if(v[h][j]!=-1) return v[h][j]; 41 | 42 | return v[h][j]=triangle[h][j]+min(minTotalUtil(triangle, h+1, j,v),minTotalUtil(triangle, h+1, j+1,v)); 43 | } 44 | int minimumTotal(vector>& triangle) { 45 | int minSum = INT_MAX; 46 | int h=triangle.size(),j; 47 | j=h; 48 | vector> v(h,vector (j,-1)); 49 | minSum=minTotalUtil(triangle, 0, 0,v); 50 | 51 | cout << minSum << endl; 52 | return minSum; 53 | 54 | } 55 | }; 56 | ``` 57 | 58 | **3. Last and best DP** 59 | 60 | **Runtime: 8 ms 61 | Memory Usage: 8.8 MB** 62 | ``` 63 | class Solution { 64 | public: 65 | 66 | int minimumTotal(vector>& triangle) { 67 | int minSum = INT_MAX; 68 | int h=triangle.size(),j; 69 | j=h; 70 | vector> v(h,vector (j,0)); 71 | v[0][0]=triangle[0][0]; 72 | for(int i=1;i>& tri) { 100 | int h=tri.size(); 101 | for(int i=1;i ---------------------------_____ 0 0 1 0 8 | 9 | 2 -> ---------------------------_____ 0 0 1 0 10 | 11 | 3 -> ---------------------------_____ 0 0 1 1 12 | 13 | 2 -> ---------------------------_____ 0 0 1 0 14 | 15 | 3 -> ---------------------------_____ 0 0 1 1 16 | 17 | 4 -> ---------------------------_____ 0 1 0 0 18 | 19 | 3 -> ---------------------------_____ 0 0 1 1 20 | 21 | Sum of total at every index _____ 0 1 6 3 22 | 23 | Taking mod by 3 at every index _ 0 1 0 0 (0%3=0 , 1%3=1 , 6%3=0 , 3%3=0) 24 | 25 | Now it is (0100) is binary form of final result i.e 4 is final answer. 26 | 27 | * if number present 3 times then by taking modulo 3 we will eleminate it's bit from result 28 | * If sum of every index bits taken mod 3 is 0 means that there is no set bit result bit 29 | * If sum of every index bits taken mod 3 is 1 means that there is set bit result bit 30 | * Now we will get final result by bits taken by mod and generate decimal form of bits** 31 | 32 | for negative single number , check if result in nums or not if not return -res || see solution 33 | ``` 34 | 35 | class Solution { 36 | public: 37 | int singleNumber(vector& nums) { 38 | long long int res=0; 39 | for(int i=0;i<32;i++) 40 | { int p=0; 41 | for(int j=0;j [N-9], [N-4] , [N-1] 14 | * Reach at Previous Stage: It's bob chance 15 | 16 | **Here If at any stage (N-9 or N-4 or N-1) bob is winner then the winner of this Game N will be ALICE.** 17 | 18 | ``` 19 | WHY????????????? 20 | ``` 21 | Think previous stage [N-9] if bob wins , 22 | If Given number is [N-9] , then it will be fresh game and Alice will start but here 23 | We found that Bob is winner, 24 | 25 | Means At this stage (N-perfect square) the person who will start the game will lose . 26 | 27 | So at this stage now Bob reaches when Given N and Alice subtract a perfect square 28 | So Bob will lose and Alice will win the game for given N. 29 | 30 | 31 | 32 | Think previous stage [N-9] if Alice wins , Then everything will be reverse 33 | [N-9] new Game , Alice start and Alice is winner. 34 | 35 | Means At this stage (N-perfect square) the person who will start the game will win . 36 | 37 | So at this stage now Bob reaches when Given N and Alice subtract a perfect square 38 | So Bob will win and Alice will lose the game for given N. 39 | 40 | **Keep in mind starting NOTE of post,** 41 | 42 | You have to try everything to declare Alice as a winner because he is starting the 43 | game and he will play optimally and bob will take move according to moves of 44 | alice. If after all combination alice can't win then declare Bob winner. 45 | 46 | 47 | 48 | **Final:** 49 | 50 | ```If any previous stage Bob is winner then Alice is winner of current stage N.``` 51 | 52 | **See the code now :)** 53 | 54 | ``` 55 | class Solution { 56 | public: 57 | 58 | bool winnerSquareGame(int n) { 59 | 60 | //Used to store previous stage 61 | vector v(n+1); 62 | 63 | //for N=1, Alice will be winner, 1 is perfect square 1-1=0 bob have no 64 | //oppertunaty 65 | v[1]='A'; 66 | 67 | //Store the perfect square till n 68 | vector sqr; 69 | for(int i=1;i<=n;i++) 70 | { 71 | if(floor(sqrt(i))==ceil(sqrt(i))) sqr.push_back(i); 72 | } 73 | 74 | //Start from =2 to n 75 | for(int i=2;i<=n;i++) 76 | { 77 | //Perfect square Alice is winner of this stage 78 | if(floor(sqrt(i))==ceil(sqrt(i))){ v[i]='A';continue; } 79 | 80 | //Go to previous stage 81 | int j=0,c=0; 82 | while(j=0) 83 | { 84 | //If at previous stage Bob is winner then 85 | //According to explanation Alice is winner :) of current stage 86 | if(v[i-sqr[j]]=='B') {v[i]='A';c=1;break;} 87 | j++; 88 | } 89 | 90 | //We did't found bob in previous stage then Bob is winner :( 91 | if(!c) v[i]='B'; 92 | } 93 | 94 | //return the verdict 95 | return v[n]=='A'?1:0; 96 | } 97 | }; 98 | ``` 99 | 100 | **Time Complexity: O( N * sqrt(N) ) 101 | Space Complexity: O(N)** 102 | 103 | ________________________________________________________________________________________________________ 104 | ________________________________________________________________________________________________________ 105 | 106 | **Hit 👍 if you like it :)** 107 | 108 | -------------------------------------------------------------------------------- /1567. Maximum Length of Subarray With Positive Product.md: -------------------------------------------------------------------------------- 1 | 2 | Problem Link: https://leetcode.com/problems/maximum-length-of-subarray-with-positive-product/ 3 | 4 | **We can have ony three possibilities in a subarray** 5 | 6 | * The count of negative number is even ,**product will be +ve** 7 | * Count of negative numberis odd ,**product will be -ve** 8 | 9 | Using this concept I have written this solution with all necessary comments 10 | Hoping It will be helpful to you. 11 | 12 | 13 | 14 | ``` 15 | class Solution { 16 | public: 17 | int getMaxLen(vector& nums) { 18 | int mx=0; //will store result 19 | int sz=nums.size(); 20 | for(int i=0;ito store starting of negatiive number 25 | //n_e ->to store end of negative number 26 | //n ->count of negative number 27 | //p ->count of positive number 28 | 29 | //We will iterate until we found zero 30 | for(j=i;j0)p++; 34 | if(nums[j]<0&&n_s==-1) { n_s=j;} //store starting index of negative number 35 | if(nums[j]<0) n_e=j; //store end index of negative number 36 | if(nums[j]==0) break; //subarray ends now because after that all the product will be 0 37 | } 38 | // cout< {1,2,-1,2,3,1,-1,2,3,4,-1,2,3} , I am taking 3 negative numbers 50 | We know that odd-1 = even 51 | We have stored starting of negative number index in n_s 52 | and end of negative number index in n_e 53 | 54 | For this example n_s=2 , n_e = 10 55 | So here two cases, if we left a negative number of n_s index then 56 | total count of negative numbers will be odd-1=even negative numbers 57 | i.e subarray will be {2,3,1,-1,2,3,4,-1,2,3} 58 | 59 | Or if we left a negative number of n_e index than 60 | total count of negative numbers will be odd-1=even negative numbers 61 | i.e subarray will be {1,2,-1,2,3,1,-1,2,3,4} 62 | 63 | So max length will be any one from these two only 64 | So we will take max length of these two 65 | */ 66 | if(n%2==1) 67 | { 68 | mx=max(j-n_s-1,mx); 69 | mx=max(n_e-i,mx); 70 | } 71 | //cout<> &v,int i,int mx,vector> &temp) 10 | { 11 | //base case 12 | if(i>=v.size()) return 0; 13 | 14 | //if we have already calculated 15 | if(temp[i][mx]!=-1) return temp[i][mx]; 16 | 17 | /*score is already greater than previous , only we have to check age 18 | if current player age is greater or equal to previous player age 19 | we can take this player score*/ 20 | 21 | if(v[i][1]>=mx) 22 | { 23 | /* if we will take this player score then for the next players age will be update 24 | take--> we will add the score of player and will go to next players by 25 | update mx to current player age v[i][1] 26 | not_take--> If we are not taking current player score then our next age will be 27 | remain same equal to previous one 28 | Return max of both one */ 29 | 30 | return temp[i][mx]=max(v[i][0]+find(v,i+1,v[i][1],temp),find(v,i+1,mx,temp)); 31 | } 32 | 33 | /*We can't take this player age because it's age is less than previous player 34 | and score is greater because we have sorted according to score*/ 35 | 36 | else 37 | return temp[i][mx]=find(v,i+1,mx,temp); 38 | 39 | } 40 | int bestTeamScore(vector& scores, vector& ages) { 41 | 42 | vector> v; 43 | for(int i=0;i> temp(1005,vector(1005,-1)); 53 | 54 | return find(v,0,0,temp); 55 | 56 | } 57 | }; 58 | ``` 59 | -------------------------------------------------------------------------------- /1771. Maximize Palindrome Length From Subsequences.md: -------------------------------------------------------------------------------- 1 | **Basic Idea:** 2 | ```Concatenate both strings and find longest palindromic subsequence and check boundary condition that one character from word1 and other corresponding character from word2.``` 3 | 4 | 5 | 6 | **1. Recursive Memoized Solution** 7 | ``` 8 | class Solution { 9 | public: 10 | 11 | //use to memoize recursive solution 12 | vector> v; 13 | 14 | /* 15 | boundary of both strings, 16 | l is length of concatenated string, 17 | ans is used to store final result 18 | */ 19 | 20 | int boundary,l,ans; 21 | 22 | //Longest palindromic string 23 | int find(string &s,int i,int j) 24 | { 25 | // i->left, j->right 26 | //if left index is greater than right then return 27 | if(i>j) return 0; 28 | 29 | //if already calculated, return result 30 | if(v[i][j]!=-1) return v[i][j]; 31 | 32 | //if we are at stage where i==j, 33 | //means here single character 34 | //count it and increase left boundary and decrease right boundary 35 | if(i==j) 36 | { 37 | return v[i][j]=1+find(s,i+1,j-1); 38 | } 39 | 40 | 41 | //if two characters are same, count these two and 42 | //increase left boundary and decrease right boundary 43 | //and call function 44 | if(s[i]==s[j]) 45 | { 46 | 47 | int k=v[i][j]=2+find(s,i+1,j-1); 48 | 49 | /* 50 | 51 | if left character is from word1 and 52 | right character is from word2 53 | then store maximum result in ans 54 | 55 | NOTE: till (boundary-1) index s stored word1 56 | and from index (boundary) s stored word2 57 | 58 | */ 59 | if(i=boundary) 60 | { 61 | ans=max(ans,k); 62 | } 63 | return k; 64 | } 65 | 66 | //if characters are not same, 67 | //try both increase left index and make right index constent 68 | // or make left constant or decrease right index 69 | // and return max of both 70 | else 71 | { 72 | return v[i][j]=max(find(s,i+1,j),find(s,i,j-1)); 73 | } 74 | } 75 | 76 | int longestPalindrome(string word1, string word2) { 77 | 78 | //store boundary of strings 79 | boundary=word1.size(); 80 | 81 | //concatenate both strings 82 | word1+=word2; 83 | 84 | //find total length of string 85 | l=word1.length(); 86 | 87 | //used to memoize solution 88 | v=vector> (l+1,vector (l+1,-1)); 89 | 90 | //call function 91 | int k=find(word1,0,l-1); 92 | 93 | 94 | //return final ans 95 | return ans; 96 | } 97 | }; 98 | ``` 99 | 100 | ------------------------------------------------------------------------------------ 101 | **2.DP Solution** 102 | ``` 103 | class Solution { 104 | public: 105 | 106 | //use to memoize recursive solution 107 | vector> v; 108 | 109 | /* 110 | boundary of both strings, 111 | l is length of concatenated string, 112 | ans is used to store final result 113 | */ 114 | 115 | int boundary,l,ans; 116 | 117 | 118 | int longestPalindrome(string word1, string word2) { 119 | 120 | //store boundary of strings 121 | boundary=word1.size(); 122 | 123 | //concatenate both strings 124 | word1+=word2; 125 | 126 | //find total length of string 127 | l=word1.length(); 128 | 129 | //used to memoize solution 130 | v=vector> (l+1,vector (l+1,0)); 131 | 132 | 133 | //single character will be palindromic 134 | for(int i=0;i=boundary) 150 | { 151 | ans=max(ans,v[i][j]); 152 | } 153 | } 154 | else 155 | //if characters are not same, 156 | //try both increase left index and make right index constent 157 | // or make left constant or decrease right index 158 | // and return max of both 159 | { 160 | v[i][j]=max(v[i-1][j],v[i-1][j+1]); 161 | } 162 | } 163 | } 164 | 165 | return ans; 166 | } 167 | }; 168 | ``` 169 | 170 | 171 | **Time Complexity : O( (m+n)^2), 172 | Time Complexity : O( (m+n)^2), m and n is length of word1 and word2** 173 | 174 | -------------------------------------------------------------------------------- /1774. Closest Dessert Cost.md: -------------------------------------------------------------------------------- 1 | 2 | Problem Link: https://leetcode.com/problems/closest-dessert-cost/ 3 | 4 | **How to approach problem** 5 | 6 | **Constraints:** Most Important Factor 7 | 8 | * n == baseCosts.length 9 | * m == toppingCosts.length 10 | * 1 <= n, m <= 10 11 | * 1 <= baseCosts[i], toppingCosts[i] <= 104 12 | * 1 <= target <= 104 13 | 14 | From the problem we can clearly see that **we have to select few choices from given array** and we can see the constraints **1 <= n, m <= 10.** 15 | 16 | **NOTE:**``` Here Recursion came into existence ``` 17 | 18 | So, lets move to problem. 19 | 20 | **We are given 3 inputs.** 21 | 1. **baseCosts** ***-> Array,*** We have to select only 1 **(Compoulsary)** from it. 22 | 1. **toppingCosts** ***-> Array,*** We have to select only 0 or more toppingcost **(** but we can select same topping atmost 2 time **)** from it. 23 | 2. **target** -> an integer representing your target price for dessert. 24 | 25 | **Aim:** 26 | Make a dessert with a total cost as close to target as possible by **selecting 1 baseCost(Compoulsary)** and select only 0 or more toppingcost **(** but we can select same topping atmost 2 time **)** from it. 27 | 28 | **Algorithm:** 29 | ``` Take each baseCost every time and select toppingCost and store ans which is closest to target``` 30 | 31 | ``` 32 | class Solution { 33 | public: 34 | 35 | //ans-> store final result 36 | //mn -> Current minimum difference b/w target and curr_price 37 | int ans=INT_MAX,mn=INT_MAX; 38 | 39 | /* 40 | i-> index of tc(toppingCosts) 41 | curr -> current cost taken 42 | tar -> Target cost 43 | */ 44 | 45 | void find(int i,vector& tc,int curr, int tar) 46 | { 47 | /* 48 | if difference b/w current cost and target cost is 49 | less than min difference , so we have to update ans 50 | and min difference because we got closest to target 51 | */ 52 | if(abs(curr-tar)=tc.size() || curr-tar>mn) return; 70 | 71 | 72 | /* Main interesting thing -> How to recurse */ 73 | /* 74 | Just put all the required conditions 75 | 76 | NOTE: We have already taken 1 baseCosts, so left that 77 | We have to select from tc(toppingCosts) 78 | 79 | In our question we have 3 conditon 80 | 1. Take ith toppingCosts and go for next (i+1)th toppingCost 81 | 2. Take ith toppingCosts 2 times and go for next (i+1)th toppingCost 82 | 3. We will not take ith toppingCosts and will select next ones 83 | */ 84 | 85 | //taking ith toppingCosts and moving to (i+1)th toppingCosts 86 | find(i+1,tc,curr+tc[i],tar); 87 | 88 | //taking ith toppingCosts 2 times and moving to (i+1)th toppingCosts 89 | find(i+1,tc,curr+2*tc[i],tar); 90 | 91 | //Without taking ith toppingCosts and move to (i+1)th toppingCosts for next one 92 | find(i+1,tc,curr,tar); 93 | 94 | 95 | } 96 | int closestCost(vector& baseCosts, vector& toppingCosts, int target) { 97 | 98 | //take each baseCost every time 99 | for(auto x:baseCosts) 100 | { 101 | //taking ith baseCost and select toppingCosts 102 | find(0,toppingCosts,x,target); 103 | } 104 | 105 | //return closest to target answer 106 | return ans; 107 | 108 | } 109 | }; 110 | ``` 111 | 112 | **Time Complexity: O(n * 3^(m)), n -> baseCosts.length,m -> toppingCosts.length 113 | Space Complexity: O(1) ,ignoring recursive stack** 114 | 115 | ----------------------------------------------------------------------------------------------------------- 116 | 117 | **Please let me know if any improvement needed** 118 | 119 | ------------------------------------------------------------- 120 | 121 | **Feel free to comment :)** 122 | 123 | **Hit 👍 , if it was helpful** 124 | -------------------------------------------------------------------------------- /372. Super Pow.md: -------------------------------------------------------------------------------- 1 | 2 | Problem Link: https://leetcode.com/problems/super-pow/ 3 | 4 | Take a brief observation: 5 | a=2 , n=[5,4,3,2,1] 6 | We have to find 2^(54321)%1337 7 | Basic Rule: (a * b)%c = (a%c * b%c )%c 8 | 9 | Now , 2^(54321) = 2^(54320) * 2^1 10 | ``` 11 | = ((2^5432)^10) * 2^1 12 | 13 | = ([((2^5430) * (2^2)]^10) * 2^1 14 | = [ [ 2^543] ^ 10 * 2^2 ] ^ 10 * 2^1 15 | . 16 | . 17 | . 18 | =[[[(2^**5**)^10 * 2^**4** ]^10 * 2^**3** ] ^10 ] * 2^**2** ] ^ 10 * 2^**1** 19 | Dont forgot to use multiplication mod property , I have not added that one in explanation 20 | Below is the implementation of this explain 21 | 22 | ``` 23 | ``` 24 | class Solution { 25 | public: 26 | int find(int a,int b) 27 | { 28 | a%=1337; 29 | int res=1; 30 | for(int i=0;i& b) { 38 | int res=1,x,f; 39 | for(int i=0;i(b,2) 12 | b-->(a,1/2) 13 | b-->(a,1/2),(c,3) 14 | c-->(b,3/2)** 15 | 16 | **a/c=? 17 | then we will go from a->b res=2 * 1 =2 18 | now we will go from b->c res=2 * 3 =6 19 | res will be 6:** 20 | 21 | **c/a=? 22 | then we will go from c->b res=(1/3) * 1 =1/3 23 | now we will go from b->a res=(1/3) * (1/2) =1/6 24 | res will be 1/6:** 25 | ``` 26 | class Solution { 27 | public: 28 | 29 | vector res; //to store final output 30 | map>> adj; //Create a map to store adjacency list 31 | 32 | void find(string x,string y,map &vis,double rs) 33 | { 34 | vis[x]=1; 35 | if(x==y){ 36 | res.push_back(rs);return; 37 | } 38 | for(int i=0;i calcEquation(vector>& equations, vector& values, vector>& queries) { 51 | 52 | ios_base::sync_with_stdio(false); 53 | cin.tie(NULL); 54 | 55 | if(equations.size()==0) return res; 56 | if(equations[0].size()==0) return res; 57 | 58 | 59 | 60 | for(int i=0;iy (2) 65 | adj[y].push_back({x,double(1)/val}); //store reverse path x/y=2 , y->x (1/2) 66 | } 67 | 68 | 69 | for(int i=0;i vis; //create visites map to check visited variables 79 | //call find function to solve query 80 | find(x,y,vis,double(1)*(1.0)); 81 | //if we didn't find val like for x/y=2 , p/q=3 82 | //we have to find x/p which is impossible so we will insert -1.00 83 | if(res.size()!=i+1) res.push_back(double(-1)); 84 | 85 | } 86 | return res; 87 | 88 | } 89 | }; 90 | ``` 91 | -------------------------------------------------------------------------------- /45. Jump Game II.md: -------------------------------------------------------------------------------- 1 | **Here is step by step three solution recursive , memoization solution and finally O(n) solution** 2 | 3 | **1. Recursive solution but it will give TLE:** 4 | ``` 5 | class Solution { 6 | public: 7 | 8 | long long int jump(vector nums , int curr, int dest) 9 | { 10 | if(curr>=dest) return 0; 11 | long long int tmp=INT_MAX; 12 | 13 | //Try Every jump 1 to nums[curr] jump 14 | //and find minimum steps need to reach to end 15 | 16 | for(int i=1;i<=nums[curr];i++) 17 | { 18 | tmp=min(tmp,1+jump(nums,curr+i,dest)); 19 | } 20 | return tmp; 21 | } 22 | 23 | int jump(vector& nums) { 24 | return jump(nums,0,nums.size()-1); 25 | } 26 | }; 27 | ``` 28 | **Time Complexity: O(k^n)**, Where, **k** is max element of nums and **n** is size of nums. 29 | **Space Complexity: O(1).** 30 | Because every time inside the recursive function it is calling itself nums[i] times and this is happening for every element (i.e n elements). 31 | 32 | 33 | **2. Memoization of recursive solution but still it is giving TLE.** 34 | 35 | ``` 36 | class Solution { 37 | public: 38 | 39 | long long int jump(vector &nums , int curr, int dest,vector &dp) 40 | { 41 | if(curr==dest) return 0; 42 | if(dp[curr]!=-1) return dp[curr]; 43 | //cout<dest) break; 48 | tmp=min(tmp,1+jump(nums,curr+i,dest,dp)); 49 | } 50 | dp[curr]=tmp; 51 | return tmp; 52 | } 53 | 54 | int jump(vector& nums) { 55 | vector dp(nums.size(),-1); 56 | return jump(nums,0,nums.size()-1,dp); 57 | } 58 | }; 59 | 60 | ``` 61 | **Time Complexity: O(k * n)**, Where, **k** is max element of nums and **n** is size of nums. 62 | **Space Complexity: O(n).** 63 | Because every time inside the recursive function it is calling itself nums[i] times and this is happening for every element (i.e n elements). But here we have stored previous calculated result, so there will be no repeation. 64 | 65 | 66 | 67 | **3. O(n) Solution (accepted)** 68 | 69 | **We run loop from 0 to size()-1 because we have to reach at last index, think just previous stage when we take jump and reach to last index (size()-1) the we have counted our jump previously and we reach to last index hence we end our journey.** 70 | 71 | ``` 72 | class Solution { 73 | public: 74 | int jump(vector& nums) { 75 | 76 | if(nums.size()<2) return 0; //base case 77 | 78 | //initialize jump=1 , we are taking jump from 0th index to the range mxjump 79 | //currjump, we can take jump from particular index 80 | //mxjump , we cango up to maximum 81 | // jump to count no. of jump 82 | int jump=1,n=nums.size(),currjmp=nums[0],mxjmp=nums[0]; 83 | 84 | int i=0; 85 | 86 | //till we reach last index, NOTE: Not necessary to cross last index 87 | while(i2 29 | 2 is pointing -1, 2 is leader of group** 30 | 31 | 32 | Now **2 is friend of 3**, Now **point 2 at index 3** 33 | _INDEX : **[ 1 , 2 ,3 ,4 , 5]** 34 | VALUES: **[ 2 , 3,-1,-1, -1]** 35 | 36 | **1 is pointing 2 , 1->2 37 | 2 is pointing 3 , 2->3 38 | 3 is pointing -1 , 3 is leader of group** 39 | 40 | 41 | Now if we start finding **leader of 1 and 2** , then **3** is the leader (**COMMON LEADER: SAME GROUP**) 42 | 43 | Now **4 is friend of 5**, Now **point 4 at index 5** 44 | _INDEX : **[ 1 , 2 ,3 ,4 , 5]** 45 | VALUES: **[ 2 , 3,-1, 5, -1]** 46 | 47 | Now we have **two** groups **{1,2,3}** and **{4,5}** , NOW go to solution line by line :) 48 | 49 | ``` 50 | class Solution { 51 | public: 52 | 53 | //It will be use to store groups 54 | vector v; 55 | 56 | //Find the leader of any group in which x lies 57 | //if not lie in any group then it is self leader 58 | int parent(int x) 59 | { 60 | //self leader 61 | if(v[x]==-1) return x; 62 | //find the leader of self parent 63 | return parent(v[x]); 64 | } 65 | 66 | //Adding 2 friends in a group 67 | void _union(int a,int b) 68 | { 69 | //find the leader of both a and b 70 | int p_a=parent(a),p_b=parent(b); 71 | 72 | //if already in same group, i.e leader of both of them are same then return 73 | if(p_a==p_b) return; 74 | /* 75 | if both of them are from different group then add both the groups 76 | and make a single common group 77 | We can do this by -> leader of 1st group is member of 2nd group 78 | and now main leader of whole group is leader of 2nd member 79 | */ 80 | v[p_a]=p_b; //v[p_a] will store the index of leader of whole group 81 | } 82 | 83 | int findCircleNum(vector>& M) { 84 | int n=M.size(); 85 | v=vector (n,-1);//there will be maximum n group, mark all as a leader 86 | 87 | //making group 88 | for(int i=0;i Memoization of recursive solution -> DP*** **-> :)** 24 | 25 | 26 | **1. Recursive Solution:** 27 | ```It will give TLE, but for better understanding of DP and memoization you have to go through it``` 28 | 29 | ``` 30 | class Solution { 31 | public: 32 | int mx=1e9+7; //used to take modulo 33 | int find(int m, int n, int N, int i, int j) 34 | { 35 | if(i<0||j<0||i>=m||j>=n) return 1; //Outside the grid 36 | if(N==0) return 0; //if we are inside the grid and we have no moves 37 | vector> dir={{-1,0},{1,0},{0,-1},{0,1}}; //used to visit all 4 directions 38 | int res=0; //final result 39 | for(auto x:dir) //visit all 4 directions 40 | { 41 | /* 42 | Here we have taken a move , hence next time our move will be (N-1) 43 | And after taking a move we will reach (i+1,j),(i-1,j),(i,j+1),(i,j-1) 44 | Store the count when we will reach to boundary, 45 | If we will reach outside grid , it will return 1 46 | else return 0; 47 | */ 48 | res+=find(m,n,N-1,i+x[0],j+x[1]); 49 | res%=mx; 50 | } 51 | return res%mx; //return the final answer after taking modulo 52 | } 53 | 54 | int findPaths(int m, int n, int N, int i, int j) { 55 | return find(m,n,N,i,j); 56 | } 57 | }; 58 | 59 | ``` 60 | ***Time Complexity: O(2^(m * n * N)) 61 | Space Complexity: O(1)*** 62 | 63 | ----------------------------------------------------------------------------------------------------------- 64 | ----------------------------------------------------------------------------------------------------------- 65 | ----------------------------------------------------------------------------------------------------------- 66 | 67 | 68 | **2. Memoization of recursive Solution:** 69 | 70 | ```Status: Accepted, Runtime: 312 ms, Memory Usage: 49.8 MB ``` 71 | * Just see the recursive solution , and look this solutionYou will found that nothing is change except few lines 72 | * Since this is recursive solution, hence there will be many subproblems will repeat again and again 73 | * Like if we have calculated for N=3 moves from (i,j) coordinate and again if we reach same state , then simply return the result , In recursive solution we again calculate it, but here we have stored result of previously calculated subproblems. 74 | * I have used 3-D vector to store result of subproblems because if you will see problem you will found that there is 3 states in our problem, **N, i, j** . At every step we change these value and achieve next state , hence use 3-D vector. 75 | * Initialize vector by -1 , we will check if any state have value not equal to -1 then means we have calculated result and result is stored in vector of this state, then Simply return result. 76 | * Just go to solution :) 77 | 78 | 79 | ``` 80 | class Solution { 81 | public: 82 | int mx=1e9+7; //used to take modulo 83 | int find(int m, int n, int N, int i, int j,vector>> &memo) 84 | { 85 | if(i<0||j<0||i>=m||j>=n) return 1; //Outside the grid 86 | if(N==0) return 0; //if we are inside the grid and we have no moves 87 | if(memo[N][i][j]!=-1) return memo[N][i][j]; //if we have already result of this state, return this 88 | vector> dir={{-1,0},{1,0},{0,-1},{0,1}}; //used to visit all 4 directions 89 | int res=0; //final result 90 | for(auto x:dir) //visit all 4 directions 91 | { 92 | /* 93 | Here we have taken a move , hence next time our move will be (N-1) 94 | And after taking a move we will reach (i+1,j),(i-1,j),(i,j+1),(i,j-1) 95 | Store the count when we will reach to boundary, 96 | If we will reach outside grid , it will return 1 97 | else return 0; 98 | */ 99 | res+=find(m,n,N-1,i+x[0],j+x[1],memo); 100 | res%=mx; 101 | } 102 | return memo[N][i][j]=res%mx; //return the final answer after taking modulo,store it in this state 103 | } 104 | 105 | int findPaths(int m, int n, int N, int i, int j) { 106 | //Here I have taken 3-d vector , because there are three states in function N,i,j 107 | vector>> memo(N+1,vector> (m,vector(n,-1))); 108 | return find(m,n,N,i,j,memo); 109 | } 110 | }; 111 | ``` 112 | ***Time Complexity: O(m * n * N) 113 | Space Complexity: O(m * n * N)*** 114 | 115 | ----------------------------------------------------------------------------------------------------------- 116 | ----------------------------------------------------------------------------------------------------------- 117 | ----------------------------------------------------------------------------------------------------------- 118 | **3. Dynammic Programming:** 119 | 120 | ```Status: Accepted, Runtime: 504 ms, Memory Usage: 65.2 MB ``` 121 | ``` 122 | class Solution { 123 | public: 124 | int mx=1e9+7; //used to take modulo 125 | int findPaths(int m, int n, int N, int i, int j) { 126 | //Initialize with 0 127 | vector>> dp(N+1,vector> (m,vector(n,0))); 128 | //return find(m,n,N,i,j,memo); 129 | vector> dir={{-1,0},{1,0},{0,-1},{0,1}}; //used for visit in all 4 directions 130 | for(int i=1;i<=N;i++) //start from move 1 to N 131 | { 132 | for(int p=0;p=m||nj<0||nj>=n) res+=1; //if we reached outside boundary increase count by 1 142 | //res+=find(m,n,N-1,i+x[0],j+x[1],v); look this and write below equation 143 | else res+=dp[i-1][ni][nj]; //(N-1->i-1,ni->p+x[0], nj-> q+x[1]) 144 | res%=mx; 145 | } 146 | dp[i][p][q]=res%mx;//store the result of this state 147 | } 148 | } 149 | } 150 | return dp[N][i][j]; //return result 151 | } 152 | }; 153 | ``` 154 | 155 | ***Time Complexity: O(m * n * N) 156 | Space Complexity: O(m * n * N)*** 157 | 158 | ----------------------------------------------------------------------------------------------------------- 159 | ----------------------------------------------------------------------------------------------------------- 160 | ----------------------------------------------------------------------------------------------------------- 161 | 162 | ***If any improvement needed feel free to comment*** **:)** 163 | 164 | -------------------------------------------------------------------------------- /765. Couples Holding Hands.md: -------------------------------------------------------------------------------- 1 | Problem Link: https://leetcode.com/problems/couples-holding-hands/ 2 | 3 | 4 | [(0,1),(2,3),(4,5),(6,7),(8,9)] -> Aim (Put pairs adjacent) 5 | 6 | Mark parent of both 0,1 -> 0 7 | Mark parent of both 2,3 -> 2 8 | Mark parent of both 4,5 -> 4 9 | . 10 | . 11 | Mark parent of both 8,9 -> 8 12 | 13 | Converted row after marking parent, e.g replace odd number n by n-1 14 | 15 | [(0,0),(2,2),(4,4),(6,6),(8,8)] 16 | 17 | Now if we draw edge from index 0 to index 1, 2 to 3, 4 to 5, of row.. we have 5 connected components 18 | 19 | __ __ __ __ __ 20 | / \ / \ / \ / \ / \ 21 | \ / \ / \ / \ / \ / 22 | 0 2 4 6 8 23 | 24 | Now, we have here n/2 = (10/2) = 5 connected components, 25 | So, for fulfilling the creteria we have to convert the given graph into n/2 26 | connected components 27 | -------------------------------------------------------------------------------- 28 | 29 | How can we do this, 30 | 31 | [(0,2),(1,3),(6,5),(8,7),(4,9)] -> Assume Given row 32 | 33 | Mark parent of (0,1) -> 0 34 | Mark parent of (2,3) -> 2 35 | Mark parent of (4,5) -> 4 36 | . 37 | . 38 | Mark parent of (8,9) -> 8 39 | 40 | Converted row after marking parent 41 | 42 | [(0,0),(0,2),(6,4),(8,6),(4,8)] 43 | 44 | Now if we draw edge from index 0 to index 1, 2 to 3, 4 to 5, of row... we have 2 connected components 45 | 46 | __ 47 | / \ 48 | \ / 49 | 0------2 50 | 51 | 6 52 | / \ 53 | / \ 54 | 8-----4 55 | 56 | But our aim is to convert the graph into n/2 connected components 57 | 58 | Hence, required number of connected components = n/2 - current connected components 59 | = 4 - 2 60 | = 2 (Our required number of swaps) 61 | 62 | For this type of graph, we can see that there can be atmost 2 edges for any vertices 63 | So by swapping any one pair the number of components will increased by 1 64 | 65 | So, after making 3 swaps 66 | * index 1 and index 2 -> [(0,1),(2,3),(6,5),(8,7),(4,9)] 67 | * index 5 and index 7 -> [(0,1),(2,3),(6,7),(8,5),(4,9)] 68 | * index 6 and index 8 -> [(0,1),(2,3),(6,7),(4,5),(8,9)] 69 | 70 | We reached to destination 71 | 72 | ``` 73 | ALGO: 74 | * If number n is odd, then replace it by (n-1) for marking parent. 75 | * Draw undirected graph b/w adjacent values (index0 <--> index1, index2 <--> index3, .....) 76 | * Count connected components c 77 | * return (N/2 -c) 78 | ``` 79 | 80 | Code: 81 | 82 | ``` 83 | class Solution { 84 | public: 85 | 86 | //visit 87 | void visit(int curr, vector> &adj, vector &vis) 88 | { 89 | if(vis[curr]==1) return; 90 | vis[curr]=1; 91 | 92 | for(auto x:adj[curr]) 93 | { 94 | visit(x,adj,vis); 95 | } 96 | } 97 | 98 | int minSwapsCouples(vector& row) { 99 | 100 | //marking parent 101 | for(auto &x:row) if(x%2) x=x-1; 102 | 103 | int n=row.size(); 104 | vector> adj(n+1); 105 | 106 | //create adjacency matrix 107 | for(int i=0;i vis(n+1,0); 118 | 119 | for(int i=0;i Memoization of recursive Solution -> Optimization of memoized solution ->DP ->*** **:)** 9 | 10 | Note: We have to find minimum attempts to find the threshold floor in worst case 11 | ***Threshold floor (tf)*** -> floor from egg will not break and for (tf+1) -> egg will break 12 | 13 | * Here worst case means we have to take both the conditions at every floor that 14 | egg is broken and egg is not broken and try to achieve highest threshold floor, 15 | * Since we are talking about worst case so we will take maximum of both this case (as high floor as much possible) 16 | And from these maximum return minimum (minimize number of attempts to find highest threshold floor) 17 | 18 | **Please Note that We have eggs always greater then 0** 19 | 20 | **Base Cases:** 21 | **i)** If number of floor is 0 then we will attempt 0 times 22 | **ii)** If number of floor is 1 then we will attempt 1 times 23 | **iii)** If we have only 1 egg then we will try from floor 1 to floor n , So , here we done n attempts 24 | Due to worst case we will try every floor and drop the egg 25 | 26 | 27 | 28 | **A) Recursive solution: It will give TLE but for better understanding do step by step** 29 | 30 | ``` 31 | class Solution { 32 | public: 33 | int find(int k,int n) 34 | { if(n==0||n==1) return n; //if no. of floor 0 , 1 return n: 35 | if(k==1) return n; // if 1 egg return number of floor 36 | int ans=1000000; 37 | for(int i=1;i<=n;i++) // try from 1 to n floor , drop every floor and find minimum 38 | { 39 | int temp=1+max(find(k-1,i-1),find(k,n-i)) ; //maximum for worst case 40 | ans=min(ans,temp); //minimum attempts from maximum temp 41 | } 42 | 43 | /* 44 | Here we have k eggs and n floor 45 | if we drop from i (i=1 to n): 46 | i) egg break , now we remain k-1 eggs and i-1 floor beacase after i floor all the eggs will break 47 | ii) egg not break , now we remain k eggs and n-i floor because before i (included) all eggs will be remain 48 | */ 49 | return ans; 50 | 51 | } 52 | int superEggDrop(int K, int N) { 53 | //K -> egg , N -> floor 54 | return find(K,N); 55 | 56 | } 57 | }; 58 | ``` 59 | 60 | ***Time Complexity: O(n * (2^min(n,k)) 61 | Space Complexity: O(1) , If we ignore space taken by stack frame*** 62 | 63 | -------------------------------------------------------------------------------------------------------------- 64 | -------------------------------------------------------------------------------------------------------------- 65 | 66 | **B) Memoization of Recursive solution : Still giving TLE** 67 | 68 | 69 | ```Suggestion , Please see recursive solution for this``` 70 | 71 | ``` 72 | class Solution { 73 | public: 74 | int find(int k,int n,vector> &memo) 75 | { if(n==0||n==1) return n; //if no. of floor 0 , 1 return n: 76 | if(k==1) return n; // if 1 egg return number of floor 77 | if(memo[k][n]!=-1) return memo[k][n]; 78 | int ans=1000000; 79 | for(int i=1;i<=n;i++) // try from 1 to n floor , drop every floor and find minimum 80 | { 81 | int temp=1+max(find(k-1,i-1,memo),find(k,n-i,memo)) ; //maximum for worst case 82 | ans=min(ans,temp); //minimum attempts from maximum temp 83 | } 84 | 85 | /* 86 | Here we have k eggs and n floor 87 | if we drop from i (i=1 to n): 88 | i) egg break , now we remain k-1 eggs and i-1 floor beacase after i floor all the eggs will break 89 | ii) egg not break , now we remain k eggs and n-i floor because before i (included) all eggs will be remain 90 | */ 91 | return memo[k][n]=ans; 92 | 93 | } 94 | int superEggDrop(int K, int N) { 95 | //K -> egg , N -> floor 96 | vector> memo(K+1,vector (N+1,-1)); 97 | return find(K,N,memo); 98 | 99 | } 100 | }; 101 | ``` 102 | 103 | ***Time Complexity: O((n^2) * k) 104 | Space Complexity: O(k * n)*** 105 | 106 | -------------------------------------------------------------------------------------------------------------- 107 | -------------------------------------------------------------------------------------------------------------- 108 | 109 | **C) Optimization of Memoization solution** 110 | 111 | ```Runtime: 124 ms , Memory Usage: 29.6 MB``` 112 | ```Suggestion , Please see recursive and memoised solution for this``` 113 | 114 | ***We will use binary search instead linear serach*** 115 | 116 | ``` 117 | class Solution { 118 | public: 119 | int find(int k,int n,vector> &memo) 120 | { if(n==0||n==1) return n; //if no. of floor 0 , 1 return n: 121 | if(k==1) return n; // if 1 egg return number of floor 122 | if(memo[k][n]!=-1) return memo[k][n]; 123 | int ans=1000000,l=1,h=n,temp=0; 124 | 125 | while(l<=h) 126 | { 127 | int mid=(l+h)/2; 128 | int left=find(k-1,mid-1,memo); //egg broken check for down floors of mid 129 | int right=find(k,n-mid,memo) ; // not broken check for up floors of mid 130 | temp=1+max(left,right); //store max of both 131 | if(left right so we will go downward 135 | { 136 | h=mid-1; 137 | } 138 | ans=min(ans,temp); //store minimum attempts 139 | } 140 | 141 | /* 142 | Here we have k eggs and n floor 143 | if we drop from i (i=1 to n): 144 | i) egg break , now we remain k-1 eggs and i-1 floor beacase after i floor all the eggs will break 145 | ii) egg not break , now we remain k eggs and n-i floor because before i (included) all eggs will be remain 146 | */ 147 | return memo[k][n]=ans; 148 | 149 | } 150 | int superEggDrop(int K, int N) { 151 | //K -> egg , N -> floor 152 | vector> memo(K+1,vector (N+1,-1)); 153 | return find(K,N,memo); 154 | 155 | } 156 | }; 157 | ``` 158 | 159 | ***Time Complexity: O((n * k) * logn ) 160 | Space Complexity: O(n * k)*** 161 | 162 | -------------------------------------------------------------------------------------------------------------- 163 | -------------------------------------------------------------------------------------------------------------- 164 | 165 | **D) Finally Wait Over : DP just look memoized solution and you will see that no change in memoized and DP , minor changes** 166 | 167 | ```Runtime: 1120 ms Memory Usage: 29.6 MB``` 168 | ```Suggestion , Please see recursive and memoised solution for this``` 169 | 170 | ``` 171 | class Solution { 172 | public: 173 | 174 | int superEggDrop(int K, int N) { 175 | if(N==0||N==1) return N; //Think for base case 176 | if(K==1) return N; 177 | 178 | vector> dp(K+1,vector (N+1,0)); 179 | for(int i=0;i<=K;i++) 180 | dp[i][0]=0,dp[i][1]=1; //Filling from base case as if N==0 ans=0 , N==1 ans=1 181 | for(int i=0;i<=N;i++) 182 | dp[0][i]=0,dp[1][i]=i; //Filling from base case as if K==0 ans=0 , K==1 ans=N, number of current floor (i) 183 | 184 | for(int i=2;i right so we will go downward 198 | { 199 | h=mid-1; 200 | } 201 | ans=min(ans,temp); //store minimum attempts 202 | } 203 | dp[i][j]=ans; 204 | } 205 | } 206 | return dp[K][N]; 207 | 208 | } 209 | }; 210 | ``` 211 | ***Time Complexity: O((n * k) * logn) 212 | Space Complexity: O(n * k)*** 213 | 214 | -------------------------------------------------------------------------------------------------------------- 215 | -------------------------------------------------------------------------------------------------------------- 216 | ***Please let me know if any improvement needed in time-complexity section*** 217 | _________________________________________________________________________________________________________ 218 | ***Feel free to comment*** **:)** 219 | 220 | **Hit 👍 , if it was helpful** 221 | -------------------------------------------------------------------------------- /All Buy and Sell Stock Problems.md: -------------------------------------------------------------------------------- 1 | Problems Link: 2 | 3 | 1) https://leetcode.com/problems/best-time-to-buy-and-sell-stock/ 4 | 2) https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ 5 | 3) https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/ 6 | 4) https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/ 7 | 5) https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/ 8 | 6) https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/ 9 | 10 | Approaches: 11 | 12 | NOTE: I have used a common approach to solve few problems, you can do other also same. 13 | 14 | **To solve this problem just start from basic similar problem. After solving these peoblems we wil reach at final this problem.** 15 | 16 | ``` I have discussed all the problems by recursive and memoization approach , so that everyone can figure out minor differences between the questions :)``` 17 | 18 | --------------------------------------------------------------------------------------------------------------- 19 | --------------------------------------------------------------------------------------------------------------- 20 | **Recursive Solution and memoize solutions:** 21 | 22 | 1. https://leetcode.com/problems/best-time-to-buy-and-sell-stock/ 23 | 24 | **You can do at most one transaction** 25 | 26 | 27 | ``` 28 | class Solution { 29 | public: 30 | int find(vector &prices, int i,int k,bool buy,vector> &v) 31 | { 32 | //if we have no stock or we have no chance of transaction(k=0) 33 | if(i>=prices.size()||k<=0) return 0; 34 | if(v[i][buy]!=-1) return v[i][buy]; 35 | 36 | if(buy) //if we are buying then next time we will sell else next time we will buy 37 | { //-prices[i], because bought stock of prices[i], expend money 38 | 39 | return v[i][buy]=max(-prices[i]+find(prices,i+1,k,!buy,v),find(prices,i+1,k,buy,v)); 40 | } 41 | else //it's time to sell , now decrease k, we have done 1 transaction 42 | { //+prices[i], because we now gain (i.e) sell our stock at rate of prices[i] 43 | return v[i][buy]=max( prices[i]+find(prices,i+1,k-1,!buy,v),find(prices,i+1,k,buy,v)); 44 | } 45 | } 46 | int maxProfit(vector& prices) { 47 | 48 | int n=prices.size(); 49 | vector> v(n,vector (2,-1)); 50 | //passing here buy=1 because we will first buy then sell 51 | //we can do atmost k=1 transaction 52 | return find(prices,0,1,1,v); 53 | } 54 | }; 55 | ``` 56 | 57 | --------------------------------------------------------------------------------------------------------------- 58 | --------------------------------------------------------------------------------------------------------------- 59 | 2. https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ 60 | 61 | **You can do as many transactions as you like** 62 | 63 | ``` 64 | class Solution { 65 | public: 66 | int find(int ind,vector &v,bool buy,vector> &memo) 67 | { 68 | if(ind>=v.size()) return 0; 69 | if(memo[ind][buy]!=-1) return memo[ind][buy]; 70 | 71 | if(buy) //if we are buying then next time we will sell else next time we will buy 72 | { //-prices[i], because bought stock of prices[i], expend money, !buy because next time sell 73 | 74 | return memo[ind][buy]=max(-v[ind]+find(ind+1,v,!buy,memo),find(ind+1,v,buy,memo)); 75 | } 76 | else //it's time to sell 77 | { //+prices[i], because we now gain (i.e) sell our stock at rate of prices[i] 78 | 79 | return memo[ind][buy]=max(v[ind]+find(ind+1,v,!buy,memo),find(ind+1,v,buy,memo)); 80 | } 81 | 82 | } 83 | int maxProfit(vector& prices) { 84 | 85 | int n=prices.size(); 86 | if(n<2) return 0; 87 | vector> v(n+1,vector(2,-1)); 88 | //passing here buy=1 because we will first buy then sell 89 | return find(0,prices,1,v); 90 | } 91 | }; 92 | ``` 93 | 94 | --------------------------------------------------------------------------------------------------------------- 95 | --------------------------------------------------------------------------------------------------------------- 96 | 3. https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii/ 97 | 98 | **You may complete at most two transactions.** 99 | 100 | ``` 101 | class Solution { 102 | public: 103 | int find(vector &prices,int ind,bool buy,int c,vector>> &memo) 104 | { 105 | //if buy =1 means we have to buy now 106 | //else we have to sell now 107 | if(ind>=prices.size()||c>=2) return 0; //counter 108 | if(memo[ind][buy][c]!=-1) return memo[ind][buy][c]; 109 | if(buy) //now we can either buy prices[i] or we can skip it and try next to buy 110 | { 111 | return memo[ind][buy][c]=max(-prices[ind]+find(prices,ind+1,!buy,c,memo),find(prices,ind+1,buy,c,memo)); 112 | } 113 | else //now we can either sell prices[i] or we can skip it and try next to sell 114 | { 115 | return memo[ind][buy][c]=max(prices[ind]+find(prices,ind+1,!buy,c+1,memo),find(prices,ind+1,buy,c,memo)); 116 | } 117 | 118 | } 119 | int maxProfit(vector& prices) { 120 | //here we can do maximum two transaction 121 | //Use 3-D vector because here three states i,k,buy/sell 122 | vector>> memo(prices.size(),vector>(2,vector(2,-1))); 123 | 124 | return find(prices,0,1,0,memo); 125 | } 126 | }; 127 | 128 | ``` 129 | 130 | --------------------------------------------------------------------------------------------------------------- 131 | --------------------------------------------------------------------------------------------------------------- 132 | 4. https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iv/ 133 | 134 | **You may complete at most k transactions.** 135 | 136 | ``` 137 | class Solution { 138 | public: 139 | int find(vector &prices,int ind,bool buy,int c,int k,vector>> &memo) 140 | { //if buy =1 means we have to buy now 141 | //else we have to sell now 142 | if(ind>=prices.size()||c>=k) return 0; //counter 143 | 144 | else if(memo[ind][buy][c]!=-1) return memo[ind][buy][c]; 145 | 146 | if(buy) //now we can either buy prices[i] or we can skip it and try next to buy 147 | { 148 | return memo[ind][buy][c]=max(-prices[ind]+find(prices,ind+1,!buy,c,k,memo),find(prices,ind+1,buy,c,k,memo)); 149 | } 150 | else //now we can either sell prices[i] or we can skip it and try next to sell 151 | { 152 | return memo[ind][buy][c]=max(prices[ind]+find(prices,ind+1,!buy,c+1,k,memo),find(prices,ind+1,buy,c,k,memo)); 153 | } 154 | 155 | } 156 | int maxProfit(int k, vector& prices) { 157 | 158 | //edge case we are not able to pick 2k points from n points, which means 159 | //we will not reach the limit no matter how we try. 160 | //if the price of day i arise, buy the stock in i-1th day and sell it at ith day. 161 | if (2 * k > prices.size()) { 162 | int res = 0; 163 | for (int i = 1; i < prices.size(); i++) { 164 | res += max(0, prices[i] - prices[i - 1]); 165 | } 166 | return res; 167 | } 168 | 169 | //here we can do maximum k transaction 170 | vector>> memo(prices.size()+1,vector>(2,vector(k+1,-1))); 171 | return find(prices,0,1,0,k,memo); 172 | } 173 | }; 174 | ``` 175 | 176 | --------------------------------------------------------------------------------------------------------------- 177 | --------------------------------------------------------------------------------------------------------------- 178 | 179 | 5. https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/ 180 | 181 | **Buy and Sell Stock with Cooldown** 182 | 183 | ``` 184 | class Solution { 185 | public: 186 | int find(int buy,vector& prices, int i,vector> &v) 187 | { 188 | if(i>=prices.size()) return 0; 189 | 190 | if(v[i][buy]!=-1) return v[i][buy]; 191 | if(buy) 192 | { 193 | int a= -prices[i]+find(!buy,prices,i+1,v); 194 | int b= find(buy,prices,i+1,v); 195 | 196 | return v[i][buy]=max(a,b); 197 | } 198 | else 199 | { 200 | int a= prices[i]+find(!buy,prices,i+2,v); 201 | int b= find(buy,prices,i+1,v); 202 | return v[i][buy]=max(a,b); 203 | } 204 | } 205 | 206 | int maxProfit(vector& prices) { 207 | int n=prices.size(); 208 | 209 | vector> v(n,vector(2,-1)); 210 | return find(1,prices,0,v); 211 | } 212 | }; 213 | ``` 214 | 215 | --------------------------------------------------------------------------------------------------------------- 216 | --------------------------------------------------------------------------------------------------------------- 217 | 218 | 6. https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/ 219 | 220 | **Buy and Sell Stock with transaction-fee** 221 | ``` 222 | class Solution { 223 | public: 224 | int find(int buy,vector& prices, int fee, int i,vector> &v) 225 | { 226 | if(i>=prices.size()) return 0; 227 | 228 | if(v[i][buy]!=-1) return v[i][buy]; 229 | if(buy) 230 | { 231 | int a= -prices[i]+find(!buy,prices,fee,i+1,v); 232 | int b= find(buy,prices,fee,i+1,v); 233 | 234 | return v[i][buy]=max(a,b); 235 | } 236 | else 237 | { 238 | int a= prices[i]+find(!buy,prices,fee,i+1,v)-fee; 239 | int b= find(buy,prices,fee,i+1,v); 240 | return v[i][buy]=max(a,b); 241 | } 242 | } 243 | int maxProfit(vector& prices, int fee) { 244 | int n=prices.size(); 245 | 246 | vector> v(n,vector(2,-1)); 247 | return find(1,prices,fee,0,v); 248 | } 249 | }; 250 | ``` 251 | --------------------------------------------------------------------------------------------------------------- 252 | --------------------------------------------------------------------------------------------------------------- 253 | 254 | **Hit ✨ if you like it :) ** 255 | **Please improve and create pull request if any improvement needed** 256 | -------------------------------------------------------------------------------- /AmazonQuestionList: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "QuestionURL": "https://leetcode.com/problems/two-sum", 4 | "Title": "Two Sum" 5 | }, 6 | { 7 | "QuestionURL": "https://leetcode.com/problems/longest-substring-without-repeating-characters", 8 | "Title": "Longest Substring Without Repeating Characters" 9 | }, 10 | { 11 | "QuestionURL": "https://leetcode.com/problems/best-time-to-buy-and-sell-stock", 12 | "Title": "Best Time to Buy and Sell Stock" 13 | }, 14 | { 15 | "QuestionURL": "https://leetcode.com/problems/word-ladder", 16 | "Title": "Word Ladder" 17 | }, 18 | { 19 | "QuestionURL": "https://leetcode.com/problems/lru-cache", 20 | "Title": "LRU Cache" 21 | }, 22 | { 23 | "QuestionURL": "https://leetcode.com/problems/number-of-islands", 24 | "Title": "Number of Islands" 25 | }, 26 | { 27 | "QuestionURL": "https://leetcode.com/problems/reorganize-string", 28 | "Title": "Reorganize String" 29 | }, 30 | { 31 | "QuestionURL": "https://leetcode.com/problems/top-k-frequent-elements", 32 | "Title": "Top K Frequent Elements" 33 | }, 34 | { 35 | "QuestionURL": "https://leetcode.com/problems/trapping-rain-water", 36 | "Title": "Trapping Rain Water" 37 | }, 38 | { 39 | "QuestionURL": "https://leetcode.com/problems/group-anagrams", 40 | "Title": "Group Anagrams" 41 | }, 42 | { 43 | "QuestionURL": "https://leetcode.com/problems/rotting-oranges", 44 | "Title": "Rotting Oranges" 45 | }, 46 | { 47 | "QuestionURL": "https://leetcode.com/problems/merge-k-sorted-lists", 48 | "Title": "Merge k Sorted Lists" 49 | }, 50 | { 51 | "QuestionURL": "https://leetcode.com/problems/course-schedule-ii", 52 | "Title": "Course Schedule II" 53 | }, 54 | { 55 | "QuestionURL": "https://leetcode.com/problems/add-two-numbers", 56 | "Title": "Add Two Numbers" 57 | }, 58 | { 59 | "QuestionURL": "https://leetcode.com/problems/course-schedule", 60 | "Title": "Course Schedule" 61 | }, 62 | { 63 | "QuestionURL": "https://leetcode.com/problems/analyze-user-website-visit-pattern", 64 | "Title": "Analyze User Website Visit Pattern" 65 | }, 66 | { 67 | "QuestionURL": "https://leetcode.com/problems/spiral-matrix", 68 | "Title": "Spiral Matrix" 69 | }, 70 | { 71 | "QuestionURL": "https://leetcode.com/problems/word-search", 72 | "Title": "Word Search" 73 | }, 74 | { 75 | "QuestionURL": "https://leetcode.com/problems/kth-largest-element-in-an-array", 76 | "Title": "Kth Largest Element in an Array" 77 | }, 78 | { 79 | "QuestionURL": "https://leetcode.com/problems/median-of-two-sorted-arrays", 80 | "Title": "Median of Two Sorted Arrays" 81 | }, 82 | { 83 | "QuestionURL": "https://leetcode.com/problems/house-robber", 84 | "Title": "House Robber" 85 | }, 86 | { 87 | "QuestionURL": "https://leetcode.com/problems/insert-delete-getrandom-o1", 88 | "Title": "Insert Delete GetRandom O(1)" 89 | }, 90 | { 91 | "QuestionURL": "https://leetcode.com/problems/maximum-subarray", 92 | "Title": "Maximum Subarray" 93 | }, 94 | { 95 | "QuestionURL": "https://leetcode.com/problems/search-in-rotated-sorted-array", 96 | "Title": "Search in Rotated Sorted Array" 97 | }, 98 | { 99 | "QuestionURL": "https://leetcode.com/problems/coin-change", 100 | "Title": "Coin Change" 101 | }, 102 | { 103 | "QuestionURL": "https://leetcode.com/problems/koko-eating-bananas", 104 | "Title": "Koko Eating Bananas" 105 | }, 106 | { 107 | "QuestionURL": "https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree", 108 | "Title": "Lowest Common Ancestor of a Binary Tree" 109 | }, 110 | { 111 | "QuestionURL": "https://leetcode.com/problems/container-with-most-water", 112 | "Title": "Container With Most Water" 113 | }, 114 | { 115 | "QuestionURL": "https://leetcode.com/problems/valid-parentheses", 116 | "Title": "Valid Parentheses" 117 | }, 118 | { 119 | "QuestionURL": "https://leetcode.com/problems/meeting-rooms-ii", 120 | "Title": "Meeting Rooms II" 121 | }, 122 | { 123 | "QuestionURL": "https://leetcode.com/problems/flood-fill", 124 | "Title": "Flood Fill" 125 | }, 126 | { 127 | "QuestionURL": "https://leetcode.com/problems/merge-intervals", 128 | "Title": "Merge Intervals" 129 | }, 130 | { 131 | "QuestionURL": "https://leetcode.com/problems/product-of-array-except-self", 132 | "Title": "Product of Array Except Self" 133 | }, 134 | { 135 | "QuestionURL": "https://leetcode.com/problems/find-first-and-last-position-of-element-in-sorted-array", 136 | "Title": "Find First and Last Position of Element in Sorted Array" 137 | }, 138 | { 139 | "QuestionURL": "https://leetcode.com/problems/edit-distance", 140 | "Title": "Edit Distance" 141 | }, 142 | { 143 | "QuestionURL": "https://leetcode.com/problems/maximum-profit-in-job-scheduling", 144 | "Title": "Maximum Profit in Job Scheduling" 145 | }, 146 | { 147 | "QuestionURL": "https://leetcode.com/problems/candy", 148 | "Title": "Candy" 149 | }, 150 | { 151 | "QuestionURL": "https://leetcode.com/problems/min-stack", 152 | "Title": "Min Stack" 153 | }, 154 | { 155 | "QuestionURL": "https://leetcode.com/problems/word-search-ii", 156 | "Title": "Word Search II" 157 | }, 158 | { 159 | "QuestionURL": "https://leetcode.com/problems/string-compression", 160 | "Title": "String Compression" 161 | }, 162 | { 163 | "QuestionURL": "https://leetcode.com/problems/concatenated-words", 164 | "Title": "Concatenated Words" 165 | }, 166 | { 167 | "QuestionURL": "https://leetcode.com/problems/maximum-frequency-after-subarray-operation", 168 | "Title": "Maximum Frequency After Subarray Operation" 169 | }, 170 | { 171 | "QuestionURL": "https://leetcode.com/problems/longest-palindromic-substring", 172 | "Title": "Longest Palindromic Substring" 173 | }, 174 | { 175 | "QuestionURL": "https://leetcode.com/problems/find-the-duplicate-number", 176 | "Title": "Find the Duplicate Number" 177 | }, 178 | { 179 | "QuestionURL": "https://leetcode.com/problems/count-zero-request-servers", 180 | "Title": "Count Zero Request Servers" 181 | }, 182 | { 183 | "QuestionURL": "https://leetcode.com/problems/generate-parentheses", 184 | "Title": "Generate Parentheses" 185 | }, 186 | { 187 | "QuestionURL": "https://leetcode.com/problems/valid-sudoku", 188 | "Title": "Valid Sudoku" 189 | }, 190 | { 191 | "QuestionURL": "https://leetcode.com/problems/rotate-image", 192 | "Title": "Rotate Image" 193 | }, 194 | { 195 | "QuestionURL": "https://leetcode.com/problems/minimum-equal-sum-of-two-arrays-after-replacing-zeros", 196 | "Title": "Minimum Equal Sum of Two Arrays After Replacing Zeros" 197 | }, 198 | { 199 | "QuestionURL": "https://leetcode.com/problems/combination-sum", 200 | "Title": "Combination Sum" 201 | }, 202 | { 203 | "QuestionURL": "https://leetcode.com/problems/palindrome-number", 204 | "Title": "Palindrome Number" 205 | }, 206 | { 207 | "QuestionURL": "https://leetcode.com/problems/roman-to-integer", 208 | "Title": "Roman to Integer" 209 | }, 210 | { 211 | "QuestionURL": "https://leetcode.com/problems/integer-to-roman", 212 | "Title": "Integer to Roman" 213 | }, 214 | { 215 | "QuestionURL": "https://leetcode.com/problems/jump-game-ii", 216 | "Title": "Jump Game II" 217 | }, 218 | { 219 | "QuestionURL": "https://leetcode.com/problems/integer-to-english-words", 220 | "Title": "Integer to English Words" 221 | }, 222 | { 223 | "QuestionURL": "https://leetcode.com/problems/subarray-sum-equals-k", 224 | "Title": "Subarray Sum Equals K" 225 | }, 226 | { 227 | "QuestionURL": "https://leetcode.com/problems/pacific-atlantic-water-flow", 228 | "Title": "Pacific Atlantic Water Flow" 229 | }, 230 | { 231 | "QuestionURL": "https://leetcode.com/problems/jump-game", 232 | "Title": "Jump Game" 233 | }, 234 | { 235 | "QuestionURL": "https://leetcode.com/problems/sliding-window-maximum", 236 | "Title": "Sliding Window Maximum" 237 | }, 238 | { 239 | "QuestionURL": "https://leetcode.com/problems/binary-tree-level-order-traversal", 240 | "Title": "Binary Tree Level Order Traversal" 241 | }, 242 | { 243 | "QuestionURL": "https://leetcode.com/problems/search-a-2d-matrix", 244 | "Title": "Search a 2D Matrix" 245 | }, 246 | { 247 | "QuestionURL": "https://leetcode.com/problems/minimum-window-substring", 248 | "Title": "Minimum Window Substring" 249 | }, 250 | { 251 | "QuestionURL": "https://leetcode.com/problems/decode-string", 252 | "Title": "Decode String" 253 | }, 254 | { 255 | "QuestionURL": "https://leetcode.com/problems/design-in-memory-file-system", 256 | "Title": "Design In-Memory File System" 257 | }, 258 | { 259 | "QuestionURL": "https://leetcode.com/problems/maximize-distance-to-closest-person", 260 | "Title": "Maximize Distance to Closest Person" 261 | }, 262 | { 263 | "QuestionURL": "https://leetcode.com/problems/largest-rectangle-in-histogram", 264 | "Title": "Largest Rectangle in Histogram" 265 | }, 266 | { 267 | "QuestionURL": "https://leetcode.com/problems/number-of-provinces", 268 | "Title": "Number of Provinces" 269 | }, 270 | { 271 | "QuestionURL": "https://leetcode.com/problems/find-all-possible-recipes-from-given-supplies", 272 | "Title": "Find All Possible Recipes from Given Supplies" 273 | }, 274 | { 275 | "QuestionURL": "https://leetcode.com/problems/next-greater-element-i", 276 | "Title": "Next Greater Element I" 277 | }, 278 | { 279 | "QuestionURL": "https://leetcode.com/problems/majority-element", 280 | "Title": "Majority Element" 281 | }, 282 | { 283 | "QuestionURL": "https://leetcode.com/problems/string-to-integer-atoi", 284 | "Title": "String to Integer (atoi)" 285 | }, 286 | { 287 | "QuestionURL": "https://leetcode.com/problems/contains-duplicate", 288 | "Title": "Contains Duplicate" 289 | }, 290 | { 291 | "QuestionURL": "https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii", 292 | "Title": "Best Time to Buy and Sell Stock II" 293 | }, 294 | { 295 | "QuestionURL": "https://leetcode.com/problems/top-k-frequent-words", 296 | "Title": "Top K Frequent Words" 297 | }, 298 | { 299 | "QuestionURL": "https://leetcode.com/problems/combinations", 300 | "Title": "Combinations" 301 | }, 302 | { 303 | "QuestionURL": "https://leetcode.com/problems/rotate-list", 304 | "Title": "Rotate List" 305 | }, 306 | { 307 | "QuestionURL": "https://leetcode.com/problems/capacity-to-ship-packages-within-d-days", 308 | "Title": "Capacity To Ship Packages Within D Days" 309 | }, 310 | { 311 | "QuestionURL": "https://leetcode.com/problems/divisible-and-non-divisible-sums-difference", 312 | "Title": "Divisible and Non-divisible Sums Difference" 313 | }, 314 | { 315 | "QuestionURL": "https://leetcode.com/problems/design-parking-system", 316 | "Title": "Design Parking System" 317 | }, 318 | { 319 | "QuestionURL": "https://leetcode.com/problems/next-permutation", 320 | "Title": "Next Permutation" 321 | }, 322 | { 323 | "QuestionURL": "https://leetcode.com/problems/invert-binary-tree", 324 | "Title": "Invert Binary Tree" 325 | }, 326 | { 327 | "QuestionURL": "https://leetcode.com/problems/reverse-integer", 328 | "Title": "Reverse Integer" 329 | }, 330 | { 331 | "QuestionURL": "https://leetcode.com/problems/single-number", 332 | "Title": "Single Number" 333 | }, 334 | { 335 | "QuestionURL": "https://leetcode.com/problems/pascals-triangle", 336 | "Title": "Pascal's Triangle" 337 | }, 338 | { 339 | "QuestionURL": "https://leetcode.com/problems/basic-calculator", 340 | "Title": "Basic Calculator" 341 | }, 342 | { 343 | "QuestionURL": "https://leetcode.com/problems/min-cost-climbing-stairs", 344 | "Title": "Min Cost Climbing Stairs" 345 | }, 346 | { 347 | "QuestionURL": "https://leetcode.com/problems/validate-binary-search-tree", 348 | "Title": "Validate Binary Search Tree" 349 | }, 350 | { 351 | "QuestionURL": "https://leetcode.com/problems/magnetic-force-between-two-balls", 352 | "Title": "Magnetic Force Between Two Balls" 353 | }, 354 | { 355 | "QuestionURL": "https://leetcode.com/problems/happy-number", 356 | "Title": "Happy Number" 357 | }, 358 | { 359 | "QuestionURL": "https://leetcode.com/problems/find-eventual-safe-states", 360 | "Title": "Find Eventual Safe States" 361 | }, 362 | { 363 | "QuestionURL": "https://leetcode.com/problems/move-zeroes", 364 | "Title": "Move Zeroes" 365 | }, 366 | { 367 | "QuestionURL": "https://leetcode.com/problems/unique-paths", 368 | "Title": "Unique Paths" 369 | }, 370 | { 371 | "QuestionURL": "https://leetcode.com/problems/distribute-candies-among-children-ii", 372 | "Title": "Distribute Candies Among Children II" 373 | }, 374 | { 375 | "QuestionURL": "https://leetcode.com/problems/fizz-buzz", 376 | "Title": "Fizz Buzz" 377 | }, 378 | { 379 | "QuestionURL": "https://leetcode.com/problems/sudoku-solver", 380 | "Title": "Sudoku Solver" 381 | }, 382 | { 383 | "QuestionURL": "https://leetcode.com/problems/longest-repeating-character-replacement", 384 | "Title": "Longest Repeating Character Replacement" 385 | }, 386 | { 387 | "QuestionURL": "https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree", 388 | "Title": "Convert Sorted Array to Binary Search Tree" 389 | }, 390 | { 391 | "QuestionURL": "https://leetcode.com/problems/lfu-cache", 392 | "Title": "LFU Cache" 393 | }, 394 | { 395 | "QuestionURL": "https://leetcode.com/problems/evaluate-division", 396 | "Title": "Evaluate Division" 397 | }, 398 | { 399 | "QuestionURL": "https://leetcode.com/problems/house-robber-iii", 400 | "Title": "House Robber III" 401 | }, 402 | { 403 | "QuestionURL": "https://leetcode.com/problems/count-the-number-of-substrings-with-dominant-ones", 404 | "Title": "Count the Number of Substrings With Dominant Ones" 405 | }, 406 | { 407 | "QuestionURL": "https://leetcode.com/problems/reverse-nodes-in-k-group", 408 | "Title": "Reverse Nodes in k-Group" 409 | }, 410 | { 411 | "QuestionURL": "https://leetcode.com/problems/alien-dictionary", 412 | "Title": "Alien Dictionary" 413 | }, 414 | { 415 | "QuestionURL": "https://leetcode.com/problems/parsing-a-boolean-expression", 416 | "Title": "Parsing A Boolean Expression" 417 | }, 418 | { 419 | "QuestionURL": "https://leetcode.com/problems/making-a-large-island", 420 | "Title": "Making A Large Island" 421 | }, 422 | { 423 | "QuestionURL": "https://leetcode.com/problems/valid-word-abbreviation", 424 | "Title": "Valid Word Abbreviation" 425 | }, 426 | { 427 | "QuestionURL": "https://leetcode.com/problems/time-based-key-value-store", 428 | "Title": "Time Based Key-Value Store" 429 | }, 430 | { 431 | "QuestionURL": "https://leetcode.com/problems/lexicographically-smallest-equivalent-string", 432 | "Title": "Lexicographically Smallest Equivalent String" 433 | }, 434 | { 435 | "QuestionURL": "https://leetcode.com/problems/target-sum", 436 | "Title": "Target Sum" 437 | }, 438 | { 439 | "QuestionURL": "https://leetcode.com/problems/snakes-and-ladders", 440 | "Title": "Snakes and Ladders" 441 | }, 442 | { 443 | "QuestionURL": "https://leetcode.com/problems/find-minimum-in-rotated-sorted-array", 444 | "Title": "Find Minimum in Rotated Sorted Array" 445 | }, 446 | { 447 | "QuestionURL": "https://leetcode.com/problems/climbing-stairs", 448 | "Title": "Climbing Stairs" 449 | }, 450 | { 451 | "QuestionURL": "https://leetcode.com/problems/middle-of-the-linked-list", 452 | "Title": "Middle of the Linked List" 453 | }, 454 | { 455 | "QuestionURL": "https://leetcode.com/problems/find-the-celebrity", 456 | "Title": "Find the Celebrity" 457 | }, 458 | { 459 | "QuestionURL": "https://leetcode.com/problems/remove-duplicate-letters", 460 | "Title": "Remove Duplicate Letters" 461 | }, 462 | { 463 | "QuestionURL": "https://leetcode.com/problems/using-a-robot-to-print-the-lexicographically-smallest-string", 464 | "Title": "Using a Robot to Print the Lexicographically Smallest String" 465 | }, 466 | { 467 | "QuestionURL": "https://leetcode.com/problems/meeting-rooms", 468 | "Title": "Meeting Rooms" 469 | }, 470 | { 471 | "QuestionURL": "https://leetcode.com/problems/lexicographically-minimum-string-after-removing-stars", 472 | "Title": "Lexicographically Minimum String After Removing Stars" 473 | }, 474 | { 475 | "QuestionURL": "https://leetcode.com/problems/task-scheduler", 476 | "Title": "Task Scheduler" 477 | }, 478 | { 479 | "QuestionURL": "https://leetcode.com/problems/reverse-linked-list", 480 | "Title": "Reverse Linked List" 481 | }, 482 | { 483 | "QuestionURL": "https://leetcode.com/problems/longest-valid-parentheses", 484 | "Title": "Longest Valid Parentheses" 485 | }, 486 | { 487 | "QuestionURL": "https://leetcode.com/problems/kth-smallest-element-in-a-bst", 488 | "Title": "Kth Smallest Element in a BST" 489 | }, 490 | { 491 | "QuestionURL": "https://leetcode.com/problems/valid-anagram", 492 | "Title": "Valid Anagram" 493 | }, 494 | { 495 | "QuestionURL": "https://leetcode.com/problems/n-queens", 496 | "Title": "N-Queens" 497 | }, 498 | { 499 | "QuestionURL": "https://leetcode.com/problems/maximize-ysum-by-picking-a-triplet-of-distinct-xvalues", 500 | "Title": "Maximize Y‑Sum by Picking a Triplet of Distinct X‑Values" 501 | }, 502 | { 503 | "QuestionURL": "https://leetcode.com/problems/binary-tree-vertical-order-traversal", 504 | "Title": "Binary Tree Vertical Order Traversal" 505 | }, 506 | { 507 | "QuestionURL": "https://leetcode.com/problems/maximal-square", 508 | "Title": "Maximal Square" 509 | }, 510 | { 511 | "QuestionURL": "https://leetcode.com/problems/first-unique-character-in-a-string", 512 | "Title": "First Unique Character in a String" 513 | }, 514 | { 515 | "QuestionURL": "https://leetcode.com/problems/longest-increasing-path-in-a-matrix", 516 | "Title": "Longest Increasing Path in a Matrix" 517 | }, 518 | { 519 | "QuestionURL": "https://leetcode.com/problems/parallel-courses", 520 | "Title": "Parallel Courses" 521 | }, 522 | { 523 | "QuestionURL": "https://leetcode.com/problems/next-greater-element-ii", 524 | "Title": "Next Greater Element II" 525 | }, 526 | { 527 | "QuestionURL": "https://leetcode.com/problems/k-th-symbol-in-grammar", 528 | "Title": "K-th Symbol in Grammar" 529 | }, 530 | { 531 | "QuestionURL": "https://leetcode.com/problems/rotate-array", 532 | "Title": "Rotate Array" 533 | }, 534 | { 535 | "QuestionURL": "https://leetcode.com/problems/daily-temperatures", 536 | "Title": "Daily Temperatures" 537 | }, 538 | { 539 | "QuestionURL": "https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph", 540 | "Title": "Number of Connected Components in an Undirected Graph" 541 | }, 542 | { 543 | "QuestionURL": "https://leetcode.com/problems/palindrome-linked-list", 544 | "Title": "Palindrome Linked List" 545 | }, 546 | { 547 | "QuestionURL": "https://leetcode.com/problems/missing-number", 548 | "Title": "Missing Number" 549 | }, 550 | { 551 | "QuestionURL": "https://leetcode.com/problems/random-pick-with-weight", 552 | "Title": "Random Pick with Weight" 553 | }, 554 | { 555 | "QuestionURL": "https://leetcode.com/problems/max-consecutive-ones-iii", 556 | "Title": "Max Consecutive Ones III" 557 | }, 558 | { 559 | "QuestionURL": "https://leetcode.com/problems/merge-sorted-array", 560 | "Title": "Merge Sorted Array" 561 | }, 562 | { 563 | "QuestionURL": "https://leetcode.com/problems/diameter-of-binary-tree", 564 | "Title": "Diameter of Binary Tree" 565 | }, 566 | { 567 | "QuestionURL": "https://leetcode.com/problems/maximum-difference-between-adjacent-elements-in-a-circular-array", 568 | "Title": "Maximum Difference Between Adjacent Elements in a Circular Array" 569 | }, 570 | { 571 | "QuestionURL": "https://leetcode.com/problems/longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit", 572 | "Title": "Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit" 573 | }, 574 | { 575 | "QuestionURL": "https://leetcode.com/problems/implement-trie-prefix-tree", 576 | "Title": "Implement Trie (Prefix Tree)" 577 | }, 578 | { 579 | "QuestionURL": "https://leetcode.com/problems/asteroid-collision", 580 | "Title": "Asteroid Collision" 581 | }, 582 | { 583 | "QuestionURL": "https://leetcode.com/problems/finding-the-users-active-minutes", 584 | "Title": "Finding the Users Active Minutes" 585 | }, 586 | { 587 | "QuestionURL": "https://leetcode.com/problems/unique-paths-ii", 588 | "Title": "Unique Paths II" 589 | }, 590 | { 591 | "QuestionURL": "https://leetcode.com/problems/subarray-sums-divisible-by-k", 592 | "Title": "Subarray Sums Divisible by K" 593 | }, 594 | { 595 | "QuestionURL": "https://leetcode.com/problems/max-area-of-island", 596 | "Title": "Max Area of Island" 597 | }, 598 | { 599 | "QuestionURL": "https://leetcode.com/problems/binary-tree-right-side-view", 600 | "Title": "Binary Tree Right Side View" 601 | }, 602 | { 603 | "QuestionURL": "https://leetcode.com/problems/3sum", 604 | "Title": "3Sum" 605 | }, 606 | { 607 | "QuestionURL": "https://leetcode.com/problems/stream-of-characters", 608 | "Title": "Stream of Characters" 609 | }, 610 | { 611 | "QuestionURL": "https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal", 612 | "Title": "Construct Binary Tree from Preorder and Inorder Traversal" 613 | }, 614 | { 615 | "QuestionURL": "https://leetcode.com/problems/kth-missing-positive-number", 616 | "Title": "Kth Missing Positive Number" 617 | }, 618 | { 619 | "QuestionURL": "https://leetcode.com/problems/subsets", 620 | "Title": "Subsets" 621 | }, 622 | { 623 | "QuestionURL": "https://leetcode.com/problems/average-of-levels-in-binary-tree", 624 | "Title": "Average of Levels in Binary Tree" 625 | }, 626 | { 627 | "QuestionURL": "https://leetcode.com/problems/zigzag-conversion", 628 | "Title": "Zigzag Conversion" 629 | }, 630 | { 631 | "QuestionURL": "https://leetcode.com/problems/find-median-from-data-stream", 632 | "Title": "Find Median from Data Stream" 633 | }, 634 | { 635 | "QuestionURL": "https://leetcode.com/problems/coin-change-ii", 636 | "Title": "Coin Change II" 637 | }, 638 | { 639 | "QuestionURL": "https://leetcode.com/problems/reorder-list", 640 | "Title": "Reorder List" 641 | }, 642 | { 643 | "QuestionURL": "https://leetcode.com/problems/max-difference-you-can-get-from-changing-an-integer", 644 | "Title": "Max Difference You Can Get From Changing an Integer" 645 | }, 646 | { 647 | "QuestionURL": "https://leetcode.com/problems/maximum-difference-between-increasing-elements", 648 | "Title": "Maximum Difference Between Increasing Elements" 649 | }, 650 | { 651 | "QuestionURL": "https://leetcode.com/problems/bulls-and-cows", 652 | "Title": "Bulls and Cows" 653 | }, 654 | { 655 | "QuestionURL": "https://leetcode.com/problems/word-break-ii", 656 | "Title": "Word Break II" 657 | }, 658 | { 659 | "QuestionURL": "https://leetcode.com/problems/evaluate-reverse-polish-notation", 660 | "Title": "Evaluate Reverse Polish Notation" 661 | }, 662 | { 663 | "QuestionURL": "https://leetcode.com/problems/length-of-last-word", 664 | "Title": "Length of Last Word" 665 | }, 666 | { 667 | "QuestionURL": "https://leetcode.com/problems/minimum-difference-in-sums-after-removal-of-elements", 668 | "Title": "Minimum Difference in Sums After Removal of Elements" 669 | }, 670 | { 671 | "QuestionURL": "https://leetcode.com/problems/longest-common-prefix", 672 | "Title": "Longest Common Prefix" 673 | }, 674 | { 675 | "QuestionURL": "https://leetcode.com/problems/recyclable-and-low-fat-products", 676 | "Title": "Recyclable and Low Fat Products" 677 | }, 678 | { 679 | "QuestionURL": "https://leetcode.com/problems/sum-of-unique-elements", 680 | "Title": "Sum of Unique Elements" 681 | }, 682 | { 683 | "QuestionURL": "https://leetcode.com/problems/decode-ways", 684 | "Title": "Decode Ways" 685 | }, 686 | { 687 | "QuestionURL": "https://leetcode.com/problems/design-tic-tac-toe", 688 | "Title": "Design Tic-Tac-Toe" 689 | }, 690 | { 691 | "QuestionURL": "https://leetcode.com/problems/find-peak-element", 692 | "Title": "Find Peak Element" 693 | }, 694 | { 695 | "QuestionURL": "https://leetcode.com/problems/recover-binary-search-tree", 696 | "Title": "Recover Binary Search Tree" 697 | }, 698 | { 699 | "QuestionURL": "https://leetcode.com/problems/palindrome-partitioning", 700 | "Title": "Palindrome Partitioning" 701 | }, 702 | { 703 | "QuestionURL": "https://leetcode.com/problems/number-of-recent-calls", 704 | "Title": "Number of Recent Calls" 705 | }, 706 | { 707 | "QuestionURL": "https://leetcode.com/problems/search-in-a-binary-search-tree", 708 | "Title": "Search in a Binary Search Tree" 709 | }, 710 | { 711 | "QuestionURL": "https://leetcode.com/problems/basic-calculator-iii", 712 | "Title": "Basic Calculator III" 713 | }, 714 | { 715 | "QuestionURL": "https://leetcode.com/problems/plates-between-candles", 716 | "Title": "Plates Between Candles" 717 | }, 718 | { 719 | "QuestionURL": "https://leetcode.com/problems/longest-consecutive-sequence", 720 | "Title": "Longest Consecutive Sequence" 721 | }, 722 | { 723 | "QuestionURL": "https://leetcode.com/problems/simplify-path", 724 | "Title": "Simplify Path" 725 | }, 726 | { 727 | "QuestionURL": "https://leetcode.com/problems/maximal-rectangle", 728 | "Title": "Maximal Rectangle" 729 | }, 730 | { 731 | "QuestionURL": "https://leetcode.com/problems/single-element-in-a-sorted-array", 732 | "Title": "Single Element in a Sorted Array" 733 | }, 734 | { 735 | "QuestionURL": "https://leetcode.com/problems/valid-palindrome", 736 | "Title": "Valid Palindrome" 737 | }, 738 | { 739 | "QuestionURL": "https://leetcode.com/problems/walls-and-gates", 740 | "Title": "Walls and Gates" 741 | } 742 | ] 743 | -------------------------------------------------------------------------------- /Google_L4_Screening.md: -------------------------------------------------------------------------------- 1 | # Sturdy Wall Questions 2 | 3 | ## Question 1: 4 | ### Question: 5 | Find the maximum length of a substring of a string with the first character lexicographically smaller than its last character. 6 | 7 | ### Sample Test Case: 8 | Input: `"abz"` 9 | Output: `3` 10 | 11 | ### Mine Provided Approach: 12 | Use a 26-size array to store the rightmost index of each character. Iterate through the string, and for each index `i`, check all characters greater than `s[i]` to find the max difference. 13 | 14 | ### Your Approach: 15 | Brute force with optimization using rightmost occurrence tracking. 16 | 17 | ### Final Solution: 18 | ```cpp 19 | int maxSubstringLength(string s) { 20 | vector rightmost(26, -1); 21 | int n = s.length(), res = 0; 22 | for (int i = 0; i < n; i++) rightmost[s[i] - 'a'] = i; 23 | for (int i = 0; i < n; i++) { 24 | for (int c = s[i] - 'a' + 1; c < 26; c++) { 25 | if (rightmost[c] > i) res = max(res, rightmost[c] - i + 1); 26 | } 27 | } 28 | return res; 29 | } 30 | ``` 31 | 32 | ## Question 2: 33 | ### Question: 34 | Given an origin airport, destination airport, and a series of flights, determine whether it is possible for a package at the origin to reach the destination. 35 | A flight is represented as departure airport, arrival airport, departure time, and arrival time. 36 | The package must only take flights such that the **departure time ≥ its arrival time** at that airport. 37 | The package starts at the origin airport at time 0. 38 | 39 | ### Sample Test Case 1: 40 | - Origin: `"NYC"` 41 | - Destination: `"SFO"` 42 | - Flights: 43 | `NYC → LAX`, Departure: `0`, Arrival: `4` 44 | `LAX → SFO`, Departure: `5`, Arrival: `7` 45 | - Output: `True` 46 | 47 | ### Sample Test Case 2: 48 | - Origin: `"NYC"` 49 | - Destination: `"SFO"` 50 | - Flights: 51 | `NYC → LAX`, Departure: `0`, Arrival: `4` 52 | `LAX → SFO`, Departure: `3`, Arrival: `5` 53 | - Output: `False` 54 | 55 | ### Mine Provided Approach: 56 | Use an adjacency list to store neighbors, and a separate map to store departure and arrival times. 57 | Traverse from the origin using current time and only consider flights whose departure time is ≥ current time. 58 | Update current time as you proceed. If the destination is reachable following these constraints, return true. 59 | 60 | ### Your Approach: 61 | Use Dijkstra-style BFS with a priority queue to always explore the earliest reachable airport. 62 | Track the earliest arrival time for each airport using a visited map. 63 | 64 | ### Final Solution: 65 | ```cpp 66 | #include 67 | #include 68 | #include 69 | #include 70 | #include 71 | #include 72 | 73 | using namespace std; 74 | 75 | bool canTransfer(string origin, string destination, vector> flights) { 76 | // Build adjacency list 77 | unordered_map>> adj; 78 | for (const auto& [from, to, dep, arr] : flights) { 79 | adj[from].emplace_back(to, dep, arr); 80 | } 81 | 82 | // Min-heap to prioritize earliest arrival times 83 | priority_queue, vector>, greater<>> pq; 84 | unordered_map visitedTime; 85 | 86 | pq.push({0, origin}); // {arrival_time, airport} 87 | visitedTime[origin] = 0; 88 | 89 | while (!pq.empty()) { 90 | auto [currTime, airport] = pq.top(); pq.pop(); 91 | 92 | if (airport == destination) return true; 93 | 94 | for (const auto& [next, dep, arr] : adj[airport]) { 95 | if (dep >= currTime) { 96 | // Only consider if we haven't visited or have a better arrival time 97 | if (!visitedTime.count(next) || visitedTime[next] > arr) { 98 | visitedTime[next] = arr; 99 | pq.push({arr, next}); 100 | } 101 | } 102 | } 103 | } 104 | 105 | return false; 106 | } 107 | ``` 108 | 109 | ### Time Complexity: 110 | - **O(E × log N)**, where: 111 | - `E` is the number of flights (edges) 112 | - `N` is the number of unique airports (nodes) 113 | - We use a min-heap to always explore the airport with the earliest possible arrival time. 114 | 115 | 116 | ## Question 3: 117 | ### Question: 118 | You’re given a string which may contain "bad pairs". 119 | A **bad pair** is defined as a pair of adjacent characters that are the same letter but in **different cases**. 120 | For example, `"xX"` is a bad pair, but `"xx"` or `"XX"` are not. 121 | Implement a solution to remove all bad pairs from the string. 122 | 123 | ### Sample Test Case: 124 | - Input: `"abxXw"` 125 | - Output: `"abw"` 126 | 127 | ### Edge Case: 128 | - Input: `""` 129 | - Output: `""` 130 | 131 | --- 132 | 133 | ### Mine Provided Approach: 134 | Use a stack-based approach to process each character. 135 | If the top of the stack and the current character form a bad pair, pop the stack. 136 | Otherwise, push the character onto the stack. 137 | 138 | ### Your Approach: 139 | Same stack-based strategy using a string as a stack. 140 | A bad pair is detected by checking `abs(stack.top() - c) == 32`. 141 | 142 | --- 143 | 144 | ### Final Solution (With Stack): 145 | ```cpp 146 | string removeBadPairs(string s) { 147 | string stack; 148 | for (char c : s) { 149 | if (!stack.empty() && abs(stack.back() - c) == 32) { 150 | stack.pop_back(); // Remove bad pair 151 | } else { 152 | stack.push_back(c); // Keep valid char 153 | } 154 | } 155 | return stack; 156 | } 157 | ``` 158 | 159 | --- 160 | 161 | ### ✅ Unit Test Cases: 162 | ```cpp 163 | void testRemoveBadPairs() { 164 | assert(removeBadPairs("abxXw") == "abw"); 165 | assert(removeBadPairs("aAa") == "a"); // "aA" removed, left with "a" 166 | assert(removeBadPairs("aAbBcC") == ""); // All cancel 167 | assert(removeBadPairs("") == ""); // Empty input 168 | assert(removeBadPairs("abc") == "abc"); // No bad pairs 169 | assert(removeBadPairs("aBAbBA") == "A"); // Complex alternating case 170 | assert(removeBadPairs("aAaAa") == "a"); // Chain cancellations 171 | assert(removeBadPairs("aBBbAa") == "a"); // Interleaved case 172 | } 173 | ``` 174 | 175 | --- 176 | 177 | ## Follow-Up 1: Unit Test Design 178 | Write tests for: 179 | - Simple cancels 180 | - Chains of bad pairs 181 | - Empty input 182 | - No bad pairs 183 | - Complex interleaved sequences 184 | - Single character strings 185 | - Already clean strings 186 | 187 | Consider modularizing your code and testing helper functions like: 188 | - `bool isBadPair(char a, char b)` 189 | 190 | --- 191 | 192 | ## Follow-Up 2: Solution Without Using Stack 193 | Use a pointer `i` to simulate stack behavior by writing valid characters in-place. 194 | 195 | ### Final Solution (No Stack): 196 | ```cpp 197 | string removeBadPairsNoStack(string s) { 198 | int i = -1; // Acts like the top index of a stack 199 | for (int j = 0; j < s.size(); ++j) { 200 | if (i >= 0 && abs(s[i] - s[j]) == 32) { 201 | --i; // Remove bad pair 202 | } else { 203 | ++i; 204 | s[i] = s[j]; // Store valid character 205 | } 206 | } 207 | return s.substr(0, i + 1); 208 | } 209 | ``` 210 | 211 | --- 212 | 213 | ### 🔍 Dry Run of `"abxXw"` (No Stack Version) 214 | 215 | | j | s[j] | i | s[0..i] | Action | 216 | |---|------|----|---------|-------------------------| 217 | | 0 | a | 0 | a | push a | 218 | | 1 | b | 1 | ab | push b | 219 | | 2 | x | 2 | abx | push x | 220 | | 3 | X | 1 | ab | pop bad pair xX | 221 | | 4 | w | 2 | abw | push w | 222 | 223 | ✅ Final Output: `"abw"` 224 | 225 | --- 226 | 227 | ### Time Complexity: 228 | - **O(n)** for both approaches 229 | - Space: 230 | - **O(n)** for the stack version 231 | - **O(1)** extra space (in-place) for the non-stack version 232 | 233 | 234 | ## Question 4: 235 | ### Question: 236 | You are given a fixed-size array of integers and a target sum `S`. 237 | You can choose any integer `x`, and **truncate all array elements greater than `x` to `x`**. 238 | Return the integer `x` such that the sum of the resulting array is as **close as possible** (min absolute difference) to the given target `S`. 239 | 240 | ### Sample Test Case: 241 | - Input: `arr = [2, 3, 5], target = 10` 242 | - Output: `5` 243 | (No element is truncated → sum is 10) 244 | 245 | - Input: `arr = [2, 3, 5], target = 6` 246 | - Output: `2` 247 | (All values > 2 become 2 → [2, 2, 2] → sum is 6) 248 | 249 | --- 250 | 251 | ### Mine Provided Approach: 252 | Sort the array. 253 | For every value `i` from 0 to target, calculate the truncated sum using prefix sum. 254 | Pick the value where `|sum - target|` is minimized. 255 | 256 | **Time Complexity:** O(n log n + target × log n) 257 | 258 | --- 259 | 260 | ### Your Approach (Optimized with Binary Search): 261 | Use binary search over possible values of `x` from `0` to `max(arr)`. 262 | 263 | For each `mid`, calculate the truncated sum: 264 | 265 | - Use prefix sums and `lower_bound` to determine how many values are ≤ `mid` 266 | - Replace all values > `mid` with `mid` and compute total sum 267 | - Keep track of the value that minimizes `|sum - target|` 268 | 269 | --- 270 | 271 | ### Final Solution: 272 | ```cpp 273 | int findBestValue(vector& arr, int target) { 274 | sort(arr.begin(), arr.end()); 275 | int n = arr.size(); 276 | vector prefix(n, 0); 277 | prefix[0] = arr[0]; 278 | 279 | for (int i = 1; i < n; ++i) { 280 | prefix[i] = prefix[i-1] + arr[i]; 281 | } 282 | 283 | int left = 0, right = arr[n - 1]; 284 | int best = 0, minDiff = INT_MAX; 285 | 286 | while (left <= right) { 287 | int mid = (left + right) / 2; 288 | int idx = lower_bound(arr.begin(), arr.end(), mid) - arr.begin(); 289 | 290 | int currSum = (idx > 0 ? prefix[idx - 1] : 0) + (n - idx) * mid; 291 | int diff = abs(currSum - target); 292 | 293 | if (diff < minDiff || (diff == minDiff && mid < best)) { 294 | best = mid; 295 | minDiff = diff; 296 | } 297 | 298 | if (currSum < target) { 299 | left = mid + 1; 300 | } else { 301 | right = mid - 1; 302 | } 303 | } 304 | 305 | return best; 306 | } 307 | ``` 308 | 309 | --- 310 | 311 | ### Time Complexity: 312 | - **O(n log n)** for sorting and prefix sum 313 | - **O(log max(arr)) × log n** for binary search with `lower_bound` 314 | - **Total:** `O(n log n + log(max_val) × log n)` 315 | 316 | --- 317 | 318 | ### Follow-Up: Can We Optimize Further? 319 | - The function that maps `x → sum after truncation` is **monotonic increasing**, so binary search is optimal. 320 | - No closed-form or greedy shortcut exists in general due to array distribution. 321 | - Pointer tricks or caching may help if there are **multiple queries**, but not for a one-shot problem. 322 | 323 | ✅ Conclusion: 324 | **Binary search** is the most efficient and clean solution — you've hit the optimal ceiling for this problem. 325 | 326 | ## Question: Pi Index Matching 327 | 328 | ### Problem Statement: 329 | You are given a string `pi` representing digits of π (pi), such as: 330 | 331 | ``` 332 | pi = "314159265359..." 333 | ``` 334 | 335 | You need to return a list of **1-based indices `i`** such that: 336 | 337 | ``` 338 | to_string(i) == pi.substr(i - 1, len(to_string(i))) 339 | ``` 340 | 341 | That is, the digits starting at index `i - 1` in `pi` match the string representation of `i`. 342 | 343 | --- 344 | 345 | ### Examples: 346 | 347 | #### Example 1: 348 | **Input:** 349 | `pi = "314159265359"` 350 | 351 | **Output:** 352 | `[3]` 353 | (Explanation: `i = 3`, `to_string(i) = "3"`, and `pi[2] == '3'`) 354 | 355 | #### Example 2: 356 | **Input:** 357 | `pi = "0123456789101112..."` 358 | 359 | **Output:** 360 | `[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, ...]` 361 | (If pi is the decimal concatenation of integers, all indices match) 362 | 363 | --- 364 | 365 | ### Constraints: 366 | - `pi.length <= 10^6` 367 | - Must return all indices `i` such that `pi.substr(i - 1, len(str(i))) == str(i)` 368 | 369 | --- 370 | 371 | ### Final C++ Solution: 372 | ```cpp 373 | #include 374 | #include 375 | #include 376 | 377 | using namespace std; 378 | 379 | vector findMatchingIndexes(const string& pi) { 380 | vector result; 381 | int n = pi.size(); 382 | 383 | for (int i = 1; ; ++i) { 384 | string si = to_string(i); 385 | int len = si.length(); 386 | 387 | if (i - 1 + len > n) break; // Stop if substring would go out of bounds 388 | 389 | if (pi.substr(i - 1, len) == si) { 390 | result.push_back(i); 391 | } 392 | } 393 | 394 | return result; 395 | } 396 | 397 | int main() { 398 | string pi = "314159265359"; 399 | vector matches = findMatchingIndexes(pi); 400 | 401 | for (int i : matches) { 402 | cout << i << " "; 403 | } 404 | cout << endl; 405 | 406 | return 0; 407 | } 408 | ``` 409 | 410 | --- 411 | 412 | ### Time Complexity: 413 | - Let `L = pi.size()` 414 | - Each `i` requires `O(log i)` time 415 | - Loop runs while `i - 1 + len(i) <= L` 416 | - ✅ **Total Complexity:** `O(L)`, efficient for up to 1 million digits 417 | 418 | --- 419 | 420 | ### Notes: 421 | - This problem combines digit indexing with pattern detection. 422 | - Ideal for problems involving digit-aligned pattern searching in numerical strings. 423 | 424 | 425 | # IP Range to Country Lookup 426 | 427 | This project implements a solution to look up the country associated with an IP address based on predefined IP ranges. 428 | 429 | ## Problem Overview 430 | 431 | Given a list of IP address ranges, each associated with a country, the task is to determine which country an input IP address belongs to. 432 | 433 | ### Example 434 | 435 | - IP Range: `{1.1.0.1 - 1.1.0.10}` -> Country: `IND` 436 | - IP Range: `{1.1.0.20 - 1.1.0.30}` -> Country: `FR` 437 | 438 | **Input:** `IP Address = 1.1.0.5` 439 | **Output:** `Country = IND` 440 | 441 | Explanation: `1.1.0.5` falls within the range `{1.1.0.1 - 1.1.0.10}`, which is mapped to `IND`. 442 | 443 | ## Approach 444 | 445 | We convert IP addresses into 32-bit integers for easier comparison. This allows us to use binary search to efficiently determine the country for a given IP address. 446 | 447 | ### Steps to Solve: 448 | 449 | 1. **Convert IP Address to Integer**: Convert the given IP address (e.g., `1.1.0.5`) into a 32-bit integer for easy comparison. 450 | 2. **Store IP Ranges**: Store the IP ranges and countries as structs, and ensure the ranges are sorted. 451 | 3. **Binary Search**: Use binary search to find the country associated with the input IP address. 452 | 453 | ## Code Implementation 454 | 455 | ```cpp 456 | #include 457 | #include 458 | #include 459 | #include 460 | #include 461 | 462 | using namespace std; 463 | 464 | // Function to convert an IP address to a 32-bit integer 465 | uint32_t ipToInt(const string& ip) { 466 | int a, b, c, d; 467 | sscanf(ip.c_str(), "%d.%d.%d.%d", &a, &b, &c, &d); 468 | return ((uint32_t)a << 24) | (b << 16) | (c << 8) | d; 469 | } 470 | 471 | // Struct to store the range of IPs and associated country 472 | struct IPRange { 473 | uint32_t start; 474 | uint32_t end; 475 | string country; 476 | }; 477 | 478 | // Function to find the country for a given IP address 479 | string findCountry(const vector& ranges, const string& ipStr) { 480 | uint32_t ip = ipToInt(ipStr); 481 | 482 | int low = 0, high = ranges.size() - 1; 483 | while (low <= high) { 484 | int mid = (low + high) / 2; 485 | if (ip >= ranges[mid].start && ip <= ranges[mid].end) { 486 | return ranges[mid].country; 487 | } else if (ip < ranges[mid].start) { 488 | high = mid - 1; 489 | } else { 490 | low = mid + 1; 491 | } 492 | } 493 | 494 | return "Unknown"; // IP not found in any range 495 | } 496 | 497 | int main() { 498 | // Define the ranges with corresponding countries 499 | vector ranges = { 500 | {ipToInt("1.1.0.1"), ipToInt("1.1.0.10"), "IND"}, 501 | {ipToInt("1.1.0.20"), ipToInt("1.1.0.30"), "FR"} 502 | }; 503 | 504 | // Query IP addresses 505 | string ip1 = "1.1.0.5"; 506 | cout << "IP: " << ip1 << " -> Country: " << findCountry(ranges, ip1) << endl; // Output: IND 507 | 508 | string ip2 = "1.1.0.25"; 509 | cout << "IP: " << ip2 << " -> Country: " << findCountry(ranges, ip2) << endl; // Output: FR 510 | 511 | string ip3 = "1.1.0.15"; 512 | cout << "IP: " << ip3 << " -> Country: " << findCountry(ranges, ip3) << endl; // Output: Unknown 513 | 514 | return 0; 515 | } 516 | ``` 517 | 518 | 519 | # Cake Cutting Problem 520 | 521 | ## Question 1: 522 | ### Question: 523 | Determine if a valid vertical cut can be made through a rectangular cake such that the cut does not intersect any of the toppings, and both resulting pieces contain at least one topping. 524 | 525 | ### Sample Test Case: 526 | Input: `Topping a (0,6,0,1); Topping b (7,8,0,4); Topping c (0,1,2,4);` 527 | Output: `True` 528 | 529 | ### Mine Provided Approach: 530 | First, model the cake as a 2D grid where each topping is represented as a rectangle. 531 | Iterate over every possible vertical cut between two columns, ensuring that the cut doesn't intersect any topping and that both resulting pieces contain at least one topping. 532 | 533 | ### Your Approach: 534 | Sweep Line Approach: Use events to represent the start and end of each topping along the x-axis. 535 | Process the events in sorted order, updating active toppings and checking if a valid vertical cut can be made at each position. 536 | 537 | ### Final Solution: 538 | ```cpp 539 | #include 540 | #include 541 | #include 542 | #include 543 | using namespace std; 544 | 545 | struct Topping { 546 | char id; 547 | int x1, x2, y1, y2; 548 | }; 549 | 550 | struct Event { 551 | int x; 552 | bool isStart; // true if start, false if end 553 | char id; 554 | 555 | bool operator<(const Event& other) const { 556 | return x < other.x || (x == other.x && isStart < other.isStart); // ends processed before starts at same x 557 | } 558 | }; 559 | 560 | bool canMakeValidCut(const vector& toppings) { 561 | vector events; 562 | unordered_set allToppings; 563 | 564 | for (const auto& t : toppings) { 565 | events.push_back({t.x1, true, t.id}); // start of a topping 566 | events.push_back({t.x2 + 1, false, t.id}); // end of a topping (non-inclusive) 567 | allToppings.insert(t.id); 568 | } 569 | 570 | sort(events.begin(), events.end()); 571 | 572 | unordered_set active; // toppings currently intersecting sweep line 573 | unordered_set ended; // toppings fully to the left of current x 574 | 575 | for (int i = 0; i < events.size(); ++i) { 576 | int currX = events[i].x; 577 | 578 | // Process all events at currX 579 | while (i < events.size() && events[i].x == currX) { 580 | if (events[i].isStart) { 581 | active.insert(events[i].id); 582 | } else { 583 | active.erase(events[i].id); 584 | ended.insert(events[i].id); 585 | } 586 | i++; 587 | } 588 | --i; // compensate for outer loop increment 589 | 590 | // At any point *between* events, check if we can cut 591 | // Valid cut: no active topping intersects this x 592 | // and there is at least one ended and one upcoming topping 593 | if (active.empty()) { 594 | int leftCount = ended.size(); 595 | int rightCount = allToppings.size() - leftCount; 596 | if (leftCount > 0 && rightCount > 0) { 597 | return true; 598 | } 599 | } 600 | } 601 | 602 | return false; 603 | } 604 | 605 | int main() { 606 | vector toppings = { 607 | {'a', 0, 6, 0, 1}, 608 | {'b', 7, 8, 0, 4}, 609 | {'c', 0, 1, 2, 4} 610 | }; 611 | 612 | cout << (canMakeValidCut(toppings) ? "True" : "False") << endl; // Should print: True 613 | return 0; 614 | } 615 | ``` 616 | 617 | # Pathfinding Problem: Counting Unique Paths in a Grid 618 | 619 | ## Problem Description 620 | 621 | You are given an `n x m` grid, starting from the bottom-left corner `(m, 0)` and aiming to reach the bottom-right corner `(m, n)`. The allowed movement directions are: 622 | - **Right** `(0, 1)` 623 | - **Diagonally Up-Right** `(-1, 1)` 624 | - **Diagonally Down-Right** `(1, 1)` 625 | 626 | You are tasked with finding the total number of unique paths from the starting point to the destination following these allowed movement rules. 627 | 628 | --- 629 | 630 | ## Solution Approach 631 | 632 | ### Initial Question: Basic Pathfinding (DFS Solution) 633 | 634 | We can solve this problem using a **Depth First Search (DFS)** approach. The general idea is to explore every possible path starting from `(m, 0)` and moving toward the destination `(m, n)` while adhering to the movement constraints. 635 | 636 | #### Key Steps: 637 | 1. **Start at (m, 0)** and recursively explore all valid moves to the right, diagonally up-right, and diagonally down-right. 638 | 2. **Terminate the search** when the destination `(m, n)` is reached, returning `1` as a valid path. 639 | 3. **Backtrack** to explore all possible routes by marking the cell as visited and unvisited during the DFS. 640 | 4. **Avoid cycles** by keeping track of visited cells in a `visited` array to prevent revisiting the same cell. 641 | 642 | #### DFS Code Snippet: 643 | 644 | ```cpp 645 | #include 646 | #include 647 | #include 648 | using namespace std; 649 | 650 | class UniquePaths { 651 | public: 652 | int countPaths(int m, int n) { 653 | vector> visited(m, vector(n, false)); 654 | return dfs(m, n, m-1, 0, visited); 655 | } 656 | 657 | private: 658 | unordered_map memo; 659 | 660 | int dfs(int m, int n, int row, int col, vector>& visited) { 661 | if (row < 0 || row >= m || col < 0 || col >= n || visited[row][col]) 662 | return 0; 663 | if (row == m-1 && col == n-1) 664 | return 1; 665 | 666 | string key = to_string(row) + "," + to_string(col); 667 | if (memo.find(key) != memo.end()) return memo[key]; 668 | 669 | visited[row][col] = true; 670 | int totalPaths = 0; 671 | 672 | totalPaths += dfs(m, n, row, col + 1, visited); 673 | totalPaths += dfs(m, n, row - 1, col + 1, visited); 674 | totalPaths += dfs(m, n, row + 1, col + 1, visited); 675 | 676 | visited[row][col] = false; 677 | memo[key] = totalPaths; 678 | return totalPaths; 679 | } 680 | }; 681 | 682 | ``` 683 | 684 | #### DFS Code Snippet With Check Points: 685 | 686 | ```cpp 687 | #include 688 | 689 | class UniquePathsWithCheckpoints { 690 | public: 691 | int countPaths(int m, int n, vector>& checkpoints) { 692 | vector> visited(m, vector(n, false)); 693 | map, bool> checkpointVisited; 694 | for (auto& p : checkpoints) 695 | checkpointVisited[p] = false; 696 | 697 | return dfs(m, n, m-1, 0, visited, checkpointVisited); 698 | } 699 | 700 | private: 701 | unordered_map memo; 702 | 703 | string generateKey(int row, int col, const map, bool>& checkpointVisited) { 704 | string key = to_string(row) + "," + to_string(col); 705 | for (auto& cp : checkpointVisited) 706 | key += "|" + to_string(cp.first.first) + "," + to_string(cp.first.second) + "=" + (cp.second ? "1" : "0"); 707 | return key; 708 | } 709 | 710 | int dfs(int m, int n, int row, int col, vector>& visited, map, bool>& checkpointVisited) { 711 | if (row < 0 || row >= m || col < 0 || col >= n || visited[row][col]) 712 | return 0; 713 | if (row == m-1 && col == n-1) { 714 | for (auto& cp : checkpointVisited) { 715 | if (!cp.second) return 0; 716 | } 717 | return 1; 718 | } 719 | 720 | string key = generateKey(row, col, checkpointVisited); 721 | if (memo.find(key) != memo.end()) return memo[key]; 722 | 723 | visited[row][col] = true; 724 | bool wasCheckpoint = false; 725 | if (checkpointVisited.find({row, col}) != checkpointVisited.end()) { 726 | checkpointVisited[{row, col}] = true; 727 | wasCheckpoint = true; 728 | } 729 | 730 | int totalPaths = 0; 731 | totalPaths += dfs(m, n, row, col + 1, visited, checkpointVisited); 732 | totalPaths += dfs(m, n, row - 1, col + 1, visited, checkpointVisited); 733 | totalPaths += dfs(m, n, row + 1, col + 1, visited, checkpointVisited); 734 | 735 | if (wasCheckpoint) { 736 | checkpointVisited[{row, col}] = false; 737 | } 738 | visited[row][col] = false; 739 | memo[key] = totalPaths; 740 | return totalPaths; 741 | } 742 | }; 743 | 744 | 745 | ``` 746 | 747 | #### DFS Code Snippet With Ordered Check Points: 748 | 749 | ```cpp 750 | class UniquePathsWithOrderedCheckpoints { 751 | public: 752 | int countPaths(int m, int n, vector>& checkpoints) { 753 | vector> visited(m, vector(n, false)); 754 | return dfs(m, n, m-1, 0, visited, checkpoints, 0); 755 | } 756 | 757 | private: 758 | unordered_map memo; 759 | 760 | string generateKey(int row, int col, int checkpointIndex) { 761 | return to_string(row) + "," + to_string(col) + "," + to_string(checkpointIndex); 762 | } 763 | 764 | int dfs(int m, int n, int row, int col, vector>& visited, vector>& checkpoints, int checkpointIndex) { 765 | if (row < 0 || row >= m || col < 0 || col >= n || visited[row][col]) 766 | return 0; 767 | if (row == m-1 && col == n-1) 768 | return (checkpointIndex == checkpoints.size()) ? 1 : 0; 769 | 770 | string key = generateKey(row, col, checkpointIndex); 771 | if (memo.find(key) != memo.end()) return memo[key]; 772 | 773 | visited[row][col] = true; 774 | bool movedCheckpoint = false; 775 | if (checkpointIndex < checkpoints.size() && make_pair(row, col) == checkpoints[checkpointIndex]) { 776 | movedCheckpoint = true; 777 | checkpointIndex++; 778 | } 779 | 780 | int totalPaths = 0; 781 | totalPaths += dfs(m, n, row, col + 1, visited, checkpoints, checkpointIndex); 782 | totalPaths += dfs(m, n, row - 1, col + 1, visited, checkpoints, checkpointIndex); 783 | totalPaths += dfs(m, n, row + 1, col + 1, visited, checkpoints, checkpointIndex); 784 | 785 | visited[row][col] = false; 786 | memo[key] = totalPaths; 787 | return totalPaths; 788 | } 789 | }; 790 | 791 | ``` 792 | 793 | # Pathfinding Problem: Complexity Analysis 794 | 795 | ## 1. Initial Problem (No Checkpoints) 796 | ✅ **Only three types of moves:** right, up-right, down-right. 797 | ✅ **Memoizing** based on `(row, col)`. 798 | 799 | - **Number of unique states:** `m * n` 800 | - **At each state:** Constant branching factor of 3 (due to 3 possible moves). 801 | 802 | ### Final Time Complexity: 803 | - `O(m × n)` 804 | - **Space complexity** is also `O(m × n)` due to the memoization table. 805 | 806 | --- 807 | 808 | ## 2. Follow-up 1 (Unordered Checkpoints) 809 | ✅ **Memoizing** based on `(row, col)` and **which checkpoints have been visited**. 810 | 811 | - **(row, col):** Can be at `m * n` positions. 812 | - For `k` checkpoints, each checkpoint can either be visited or not, resulting in `2^k` possible visited states. 813 | 814 | ### Final Time Complexity: 815 | - `O(m × n × 2^k)` 816 | - **Space complexity** is also `O(m × n × 2^k)` due to memoization. 817 | 818 | ⚡ **Note:** `2^k` becomes very large if `k` (number of checkpoints) is large, but manageable for small `k` (typically `k ≤ 15-20`). 819 | 820 | --- 821 | 822 | ## 3. Follow-up 2 (Ordered Checkpoints) 823 | ✅ **Memoizing** based on `(row, col, checkpointIndex)`. 824 | 825 | - **(row, col):** Can be at `m * n` positions. 826 | - **checkpointIndex:** Can be from 0 to `k` (number of checkpoints). 827 | 828 | ### Final Time Complexity: 829 | - `O(m × n × k)` 830 | - **Space complexity** is also `O(m × n × k)`. 831 | 832 | ⚡ **Note:** This version is much faster than the unordered version because it doesn't require handling `2^k` combinations. 833 | 834 | 835 | # Template String Replacement Problem 836 | ## Question 1: 837 | ### Question: 838 | You are given a map as a template with key-value pairs, and an input string. The task is to replace any placeholders (i.e., `%%`) in the input string with the corresponding values from the template map. The process continues recursively until no more placeholders can be replaced. 839 | 840 | ### Example 841 | 842 | Given Map: 843 | 844 | ```cpp 845 | { 846 | "X": "123", 847 | "Y": "456_%X%" 848 | } 849 | ``` 850 | 851 | ### Sample Test Case: 852 | Input: `"%X%_%Y%"` 853 | Output: `"123_456_123"` 854 | 855 | 856 | ### Final Solution: 857 | ```cpp 858 | #include 859 | #include 860 | #include 861 | #include 862 | using namespace std; 863 | 864 | string replaceTemplate(const string &input, const unordered_map &templateMap) { 865 | string result = ""; 866 | stack st; 867 | int n = input.length(); 868 | int i = 0; 869 | 870 | while (i < n) { 871 | if (input[i] == '%') { 872 | // Handle the case where we found a '%' start 873 | int start = i + 1; 874 | while (i < n && input[i] != '%') { 875 | i++; 876 | } 877 | int end = i; // mark the end of the placeholder 878 | string placeholder = input.substr(start, end - start); 879 | 880 | // Check if placeholder exists in templateMap 881 | if (templateMap.find(placeholder) != templateMap.end()) { 882 | string replacement = templateMap.at(placeholder); 883 | for (char c : replacement) { 884 | st.push(c); // Push the replacement string characters to the stack 885 | } 886 | } else { 887 | // Placeholder not found, just put it as is 888 | st.push('%'); 889 | for (char c : placeholder) { 890 | st.push(c); 891 | } 892 | st.push('%'); 893 | } 894 | } else { 895 | // Handle regular characters (numbers, underscores) 896 | st.push(input[i]); 897 | } 898 | i++; 899 | } 900 | 901 | // Reconstruct the result from the stack 902 | while (!st.empty()) { 903 | result = st.top() + result; 904 | st.pop(); 905 | } 906 | return result; 907 | } 908 | 909 | int main() { 910 | unordered_map templateMap = { 911 | {"X", "123"}, 912 | {"Y", "456_%X%"} 913 | }; 914 | 915 | string input = "%X%_%Y%"; 916 | 917 | string output = replaceTemplate(input, templateMap); 918 | 919 | cout << "Output: " << output << endl; 920 | 921 | return 0; 922 | } 923 | ``` 924 | 925 | # Restaurant Waitlist System Design 926 | 927 | ## Problem Statement 928 | 929 | Design a system to manage a restaurant waitlist with the following requirements: 930 | 931 | 1. **Add Customer Groups**: New customer groups can be added to the waitlist. 932 | 2. **Remove Customer Groups**: A customer group can leave the waitlist at any time. 933 | 3. **Assign Table**: Given a table size, find the group that best fits the table. A group is eligible for a table if its size is ≤ table size, and among eligible groups, the one that has been waiting the longest should be assigned the table. 934 | 935 | ## Approach 936 | 937 | We use a combination of: 938 | - A **map** (`map, vector>, greater<>>>`) to store groups, where keys represent group sizes and the values are min-heaps ordered by their arrival times. 939 | - An **unordered_map** (`unordered_map`) to track whether a group is still waiting or has left. 940 | - A **timer** variable to track the order of arrival. 941 | 942 | ### Operations: 943 | 1. **Add Group**: 944 | - For each new group, the group size is used to determine the key in the map. The arrival time (a timer) is used to ensure we prioritize earlier arrivals when two groups have the same size. 945 | - The group’s waiting status is set to true when it is added. 946 | 947 | 2. **Remove Group**: 948 | - When a group leaves, we mark its status as not waiting but don't remove it from the heap immediately. This allows us to "lazy delete" invalid groups later. 949 | 950 | 3. **Assign Table**: 951 | - Given a table size, we find the largest group that can fit (whose size ≤ table size). The group with the smallest arrival time (earliest) is chosen from among the largest groups. 952 | 953 | ### Optimizations: 954 | - **Map**: We use a `map>>` instead of `unordered_map` because `map` keeps the keys (group sizes) sorted, which allows for efficient searching for the largest group size ≤ table size. 955 | - **Lazy Deletion**: When a group leaves, it is not immediately removed from the heap. Instead, we remove it lazily during the table assignment process when we encounter an invalid (non-waiting) group. 956 | 957 | ### Updated Design 958 | 959 | ```cpp 960 | #include 961 | #include 962 | #include 963 | #include 964 | #include 965 | using namespace std; 966 | 967 | class WaitList { 968 | private: 969 | // groupSize -> minHeap of (arrivalTime, groupId) 970 | map, vector>, greater<>>> groupSizeMap; 971 | unordered_map isWaiting; // groupId -> true/false 972 | int timer = 0; // to assign arrival order 973 | 974 | public: 975 | // Add new customer group 976 | void addGroup(int groupId, int groupSize) { 977 | groupSizeMap[groupSize].push({timer++, groupId}); 978 | isWaiting[groupId] = true; 979 | } 980 | 981 | // A group leaves 982 | void removeGroup(int groupId) { 983 | isWaiting[groupId] = false; 984 | } 985 | 986 | // Find eligible group for table 987 | int findGroup(int tableSize) { 988 | // Find the largest groupSize <= tableSize 989 | auto it = groupSizeMap.upper_bound(tableSize); // strictly greater 990 | if (it == groupSizeMap.begin()) { 991 | return -1; // no group fits 992 | } 993 | --it; // step back to <= tableSize 994 | 995 | while (true) { 996 | auto& heap = it->second; 997 | while (!heap.empty()) { 998 | auto [arriveTime, groupId] = heap.top(); 999 | if (isWaiting[groupId]) { 1000 | isWaiting[groupId] = false; // group assigned 1001 | heap.pop(); 1002 | return groupId; 1003 | } 1004 | heap.pop(); // lazy removal of invalid groups 1005 | } 1006 | if (it == groupSizeMap.begin()) break; 1007 | --it; // check next smaller groupSize 1008 | } 1009 | return -1; // no valid group found 1010 | } 1011 | }; 1012 | ``` 1013 | 1014 | ### Optimized 1015 | ```cpp 1016 | #include 1017 | using namespace std; 1018 | 1019 | class WaitList { 1020 | private: 1021 | map>> groupSizeToGroups; // groupSize -> list of {arrivalTime, groupId} 1022 | unordered_map>::iterator> groupIdToNode; // groupId -> node in list 1023 | int arrivalTime = 0; // incrementing timer to maintain arrival order 1024 | 1025 | public: 1026 | // Add new group 1027 | void addGroup(int groupId, int groupSize) { 1028 | groupSizeToGroups[groupSize].push_back({arrivalTime++, groupId}); 1029 | auto it = groupSizeToGroups[groupSize].end(); 1030 | --it; // iterator to the newly added group 1031 | groupIdToNode[groupId] = it; 1032 | } 1033 | 1034 | // Group leaves 1035 | void removeGroup(int groupId) { 1036 | if (groupIdToNode.count(groupId)) { 1037 | auto it = groupIdToNode[groupId]; 1038 | int size = it->first; // but we don't know size directly 1039 | for (auto& [sz, lst] : groupSizeToGroups) { 1040 | if (lst.empty()) continue; 1041 | if (groupId == it->second) { 1042 | lst.erase(it); 1043 | break; 1044 | } 1045 | } 1046 | groupIdToNode.erase(groupId); 1047 | } 1048 | } 1049 | 1050 | // Assign table 1051 | int assignTable(int tableSize) { 1052 | auto it = groupSizeToGroups.upper_bound(tableSize); 1053 | if (it == groupSizeToGroups.begin()) return -1; // no group fits 1054 | --it; // largest groupSize <= tableSize 1055 | if (it->second.empty()) return -1; // no group waiting 1056 | 1057 | // Pick earliest arrival group 1058 | int groupId = it->second.front().second; 1059 | groupIdToNode.erase(groupId); 1060 | it->second.pop_front(); 1061 | return groupId; 1062 | } 1063 | }; 1064 | ``` 1065 | 1066 | ### More Optimization 1067 | ```cpp 1068 | #include 1069 | using namespace std; 1070 | 1071 | class WaitList { 1072 | private: 1073 | map> groupSizeToGroups; // groupSize -> list of groupId (maintains arrival order) 1074 | unordered_map::iterator>> groupIdToNode; // groupId -> {groupSize, node in list} 1075 | 1076 | public: 1077 | // Add a new group 1078 | void addGroup(int groupId, int groupSize) { 1079 | groupSizeToGroups[groupSize].push_back(groupId); 1080 | auto it = prev(groupSizeToGroups[groupSize].end()); // iterator to the newly added group 1081 | groupIdToNode[groupId] = {groupSize, it}; 1082 | } 1083 | 1084 | // Remove a group 1085 | void removeGroup(int groupId) { 1086 | if (groupIdToNode.count(groupId)) { 1087 | auto [size, it] = groupIdToNode[groupId]; 1088 | groupSizeToGroups[size].erase(it); 1089 | if (groupSizeToGroups[size].empty()) { 1090 | groupSizeToGroups.erase(size); // optional: clean up empty sizes 1091 | } 1092 | groupIdToNode.erase(groupId); 1093 | } 1094 | } 1095 | 1096 | // Assign a table 1097 | int assignTable(int tableSize) { 1098 | auto it = groupSizeToGroups.upper_bound(tableSize); 1099 | if (it == groupSizeToGroups.begin()) return -1; // no group fits 1100 | --it; // largest groupSize <= tableSize 1101 | if (it->second.empty()) return -1; 1102 | 1103 | int groupId = it->second.front(); // get the earliest arriving group 1104 | it->second.pop_front(); // remove from list 1105 | groupIdToNode.erase(groupId); 1106 | if (it->second.empty()) { 1107 | groupSizeToGroups.erase(it); // optional: clean up 1108 | } 1109 | return groupId; 1110 | } 1111 | }; 1112 | ``` 1113 | ### ✨ Time Complexities: 1114 | 1115 | | Operation | Time Complexity | 1116 | |----------------|-------------------| 1117 | | `addGroup` | O(log M) | 1118 | | `removeGroup` | O(1) | 1119 | | `assignTable` | O(log M) | 1120 | 1121 | 1122 | ### ✨ Problem Statement: 1123 | You are given a sorted array of strings and a prefix. The task is to return the number of strings in the array that start with the given prefix. 1124 | 1125 | --- 1126 | 1127 | ### 🛠️ Approaches: 1128 | 1129 | #### 1. Brute Force Approach: 1130 | **Description:** 1131 | Iterate over each element in the array and check if the element starts with the given prefix. 1132 | 1133 | **Time Complexity:** O(n * m), where: 1134 | - `n` is the number of strings in the array. 1135 | - `m` is the average length of the strings. 1136 | 1137 | **Steps:** 1138 | 1. Iterate through each string in the array. 1139 | 2. For each string, check if it starts with the given prefix using string functions like `startswith` or equivalent. 1140 | 3. Maintain a count and return the result after iterating through all strings. 1141 | 1142 | **Example Code:** 1143 | 1144 | ```cpp 1145 | int countPrefix(const vector& arr, const string& prefix) { 1146 | int count = 0; 1147 | for (const string& s : arr) { 1148 | if (s.substr(0, prefix.length()) == prefix) { 1149 | count++; 1150 | } 1151 | } 1152 | return count; 1153 | } 1154 | ``` 1155 | ### Trie Approach 1156 | ```cpp 1157 | struct TrieNode { 1158 | unordered_map children; 1159 | int count = 0; // frequency of words passing through this node 1160 | }; 1161 | 1162 | void insert(TrieNode* root, const string& word) { 1163 | TrieNode* node = root; 1164 | for (char c : word) { 1165 | if (node->children.find(c) == node->children.end()) { 1166 | node->children[c] = new TrieNode(); 1167 | } 1168 | node = node->children[c]; 1169 | node->count++; 1170 | } 1171 | } 1172 | 1173 | int countPrefix(TrieNode* root, const string& prefix) { 1174 | TrieNode* node = root; 1175 | for (char c : prefix) { 1176 | if (node->children.find(c) == node->children.end()) { 1177 | return 0; // no such prefix exists 1178 | } 1179 | node = node->children[c]; 1180 | } 1181 | return node->count; 1182 | } 1183 | ``` 1184 | ### Binary Search Approach 1185 | ```cpp 1186 | int countPrefix(const vector& arr, const string& prefix) { 1187 | int left = lower_bound(arr.begin(), arr.end(), prefix) - arr.begin(); 1188 | string prefix_end = prefix; 1189 | prefix_end[prefix_end.size() - 1]++; // Increment last character to find the end 1190 | int right = lower_bound(arr.begin(), arr.end(), prefix_end) - arr.begin(); 1191 | return right - left; 1192 | } 1193 | ``` 1194 | 1195 | # Sturdy Wall Builder 1196 | 1197 | This program calculates the number of ways to build a sturdy wall of a specified height and width, using bricks of given sizes. The key condition is that adjacent rows should not align at the same positions where the bricks end, except at the ends of the wall. 1198 | 1199 | ### Problem Description 1200 | 1201 | You are given: 1202 | - **height**: The height of the wall (number of rows). 1203 | - **width**: The width of the wall (length of each row). 1204 | - **bricks**: An array of brick sizes, each brick has height 1 and width as described by the array. Each brick can be used an infinite number of times. 1205 | 1206 | The program calculates how many ways you can arrange the bricks to form a sturdy wall, ensuring that adjacent rows do not align their brick ends at the same positions except at the wall edges. 1207 | 1208 | ### Key Constraints 1209 | - Rows in the wall must be exactly `width` units long. 1210 | - Adjacent rows must not align at the same positions except at the start and end of the wall. 1211 | 1212 | ### Approach 1213 | 1214 | The solution uses a **recursive depth-first search (DFS)** strategy combined with **memoization** to efficiently compute the number of valid ways to build the wall. Each row's brick positions (cut points) are stored and used to ensure the adjacency condition is met. 1215 | 1216 | 1. **Row Configuration Generation**: For a given row width, generate all possible ways to fill the row using the given bricks and store the cut positions. 1217 | 2. **DFS with Memoization**: Recursively build the wall row by row, making sure that no adjacent rows share the same cut positions (except at the wall edges). 1218 | 3. **Memoization**: To avoid recalculating the same state (row and cut positions), results are stored using memoization. 1219 | 1220 | ### Time Complexity 1221 | 1222 | - **Generating Row Configurations**: This step is exponential with respect to the width of the wall (since we try every combination of brick sizes). 1223 | - **DFS**: The recursive depth is proportional to the height of the wall, and for each row, we explore all possible valid row configurations, ensuring that no cuts from adjacent rows align. 1224 | 1225 | ### Example 1226 | 1227 | Given the inputs: 1228 | - **Height**: 2 1229 | - **Width**: 3 1230 | - **Bricks**: `[1, 2]` 1231 | 1232 | The program will output the number of ways to build the wall. For this example, the result is `4` because there are 4 valid configurations. 1233 | 1234 | ### Code Explanation 1235 | 1236 | #### 1. `buildRows` Function 1237 | Generates all possible row configurations using the given brick sizes and stores the cut positions for each configuration. 1238 | 1239 | #### 2. `dfs` Function 1240 | Recursively builds the wall row by row, ensuring no cuts from adjacent rows align (except at the wall boundaries). Uses memoization to store previously computed results to optimize the solution. 1241 | 1242 | #### 3. `isCompatible` Function 1243 | Checks whether two rows’ cut positions are compatible, meaning they don't align at the same positions except at the wall edges. 1244 | 1245 | #### 4. `toString` Function 1246 | Converts the cut positions into a string format for easy use in memoization. 1247 | 1248 | ### Running the Program 1249 | 1250 | 1. Clone the repository to your local machine. 1251 | 2. Compile the C++ code using your preferred C++ compiler. 1252 | 1253 | ```cpp 1254 | #include 1255 | using namespace std; 1256 | 1257 | const int MOD = 1e9 + 7; 1258 | 1259 | vector> possibleRows; // Stores all possible row configurations (cut positions) 1260 | unordered_map memo; // Memoization to avoid recomputation 1261 | vector bricks; // The list of available brick sizes 1262 | int wallHeight, wallWidth; // Height and Width of the wall 1263 | 1264 | // Function to recursively build all possible row configurations 1265 | void buildRows(int pos, vector& cuts) { 1266 | if (pos == wallWidth) { // If the row is filled exactly to the required width 1267 | possibleRows.push_back(cuts); // Store the cut positions of this row 1268 | return; 1269 | } 1270 | for (int brick : bricks) { // Try placing each brick at the current position 1271 | if (pos + brick <= wallWidth) { // Ensure we do not exceed the width of the wall 1272 | if (pos + brick != wallWidth) cuts.push_back(pos + brick); // Add cut if not at the end of the row 1273 | buildRows(pos + brick, cuts); // Recurse to the next position 1274 | if (pos + brick != wallWidth) cuts.pop_back(); // Backtrack by removing the last cut 1275 | } 1276 | } 1277 | } 1278 | 1279 | // Function to check if two rows' cuts are compatible 1280 | bool isCompatible(const vector& prev, const vector& curr) { 1281 | int i = 0, j = 0; 1282 | while (i < prev.size() && j < curr.size()) { 1283 | if (prev[i] == curr[j]) return false; // If the cuts align, they are not compatible 1284 | if (prev[i] < curr[j]) i++; // Move to the next cut in the previous row 1285 | else j++; // Move to the next cut in the current row 1286 | } 1287 | return true; // If no cuts overlap, the rows are compatible 1288 | } 1289 | 1290 | // Convert the cut vector to a string for memoization 1291 | string toString(const vector& cuts) { 1292 | string s; 1293 | for (int x : cuts) { 1294 | s += to_string(x) + ","; 1295 | } 1296 | return s; 1297 | } 1298 | 1299 | // Recursive DFS function to build the wall row by row 1300 | int dfs(int row, vector& prevCuts) { 1301 | if (row == wallHeight) return 1; // If we've successfully built all rows, return 1 1302 | 1303 | string key = to_string(row) + "#" + toString(prevCuts); // Key for memoization 1304 | if (memo.count(key)) return memo[key]; // If this state has been computed before, return it 1305 | 1306 | int ways = 0; 1307 | for (auto& cuts : possibleRows) { // Try each possible row configuration 1308 | if (isCompatible(prevCuts, cuts)) { // Check if the current row is compatible with the previous one 1309 | ways = (ways + dfs(row + 1, cuts)) % MOD; // Recurse to the next row 1310 | } 1311 | } 1312 | 1313 | return memo[key] = ways; // Memoize the result for this state 1314 | } 1315 | 1316 | // Main function to build the wall and return the number of ways 1317 | int buildWall(int height, int width, vector& brickSizes) { 1318 | wallHeight = height; 1319 | wallWidth = width; 1320 | bricks = brickSizes; 1321 | possibleRows.clear(); // Clear any previous row configurations 1322 | memo.clear(); // Clear the memoization cache 1323 | 1324 | vector cuts; 1325 | buildRows(0, cuts); // Generate all possible row configurations 1326 | 1327 | vector emptyCuts; // Starting with an empty previous row 1328 | return dfs(0, emptyCuts); // Start building the wall from the first row 1329 | } 1330 | 1331 | // Main function to test the program 1332 | int main() { 1333 | int height = 2, width = 3; 1334 | vector brickSizes = {1, 2}; 1335 | cout << buildWall(height, width, brickSizes) << endl; // Output the number of ways 1336 | return 0; 1337 | } 1338 | ``` 1339 | 1340 | 1341 | ## More problems to look 1342 | - https://leetcode.com/problems/check-if-grid-can-be-cut-into-sections/description/ 1343 | 1344 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### LeetCode_Solution 2 | -------------------------------------------------------------------------------- /VisaQuestion: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "QuestionURL": "https://leetcode.com/problems/two-sum", 4 | "Title": "Two Sum" 5 | }, 6 | { 7 | "QuestionURL": "https://leetcode.com/problems/longest-substring-without-repeating-characters", 8 | "Title": "Longest Substring Without Repeating Characters" 9 | }, 10 | { 11 | "QuestionURL": "https://leetcode.com/problems/median-of-two-sorted-arrays", 12 | "Title": "Median of Two Sorted Arrays" 13 | }, 14 | { 15 | "QuestionURL": "https://leetcode.com/problems/longest-palindromic-substring", 16 | "Title": "Longest Palindromic Substring" 17 | }, 18 | { 19 | "QuestionURL": "https://leetcode.com/problems/roman-to-integer", 20 | "Title": "Roman to Integer" 21 | }, 22 | { 23 | "QuestionURL": "https://leetcode.com/problems/longest-common-prefix", 24 | "Title": "Longest Common Prefix" 25 | }, 26 | { 27 | "QuestionURL": "https://leetcode.com/problems/3sum", 28 | "Title": "3Sum" 29 | }, 30 | { 31 | "QuestionURL": "https://leetcode.com/problems/valid-parentheses", 32 | "Title": "Valid Parentheses" 33 | }, 34 | { 35 | "QuestionURL": "https://leetcode.com/problems/search-in-rotated-sorted-array", 36 | "Title": "Search in Rotated Sorted Array" 37 | }, 38 | { 39 | "QuestionURL": "https://leetcode.com/problems/trapping-rain-water", 40 | "Title": "Trapping Rain Water" 41 | }, 42 | { 43 | "QuestionURL": "https://leetcode.com/problems/group-anagrams", 44 | "Title": "Group Anagrams" 45 | }, 46 | { 47 | "QuestionURL": "https://leetcode.com/problems/maximum-subarray", 48 | "Title": "Maximum Subarray" 49 | }, 50 | { 51 | "QuestionURL": "https://leetcode.com/problems/divisor-game", 52 | "Title": "Divisor Game" 53 | }, 54 | { 55 | "QuestionURL": "https://leetcode.com/problems/plus-one", 56 | "Title": "Plus One" 57 | }, 58 | { 59 | "QuestionURL": "https://leetcode.com/problems/text-justification", 60 | "Title": "Text Justification" 61 | }, 62 | { 63 | "QuestionURL": "https://leetcode.com/problems/search-a-2d-matrix", 64 | "Title": "Search a 2D Matrix" 65 | }, 66 | { 67 | "QuestionURL": "https://leetcode.com/problems/word-search", 68 | "Title": "Word Search" 69 | }, 70 | { 71 | "QuestionURL": "https://leetcode.com/problems/best-time-to-buy-and-sell-stock", 72 | "Title": "Best Time to Buy and Sell Stock" 73 | }, 74 | { 75 | "QuestionURL": "https://leetcode.com/problems/count-nodes-with-the-highest-score", 76 | "Title": "Count Nodes With the Highest Score" 77 | }, 78 | { 79 | "QuestionURL": "https://leetcode.com/problems/two-furthest-houses-with-different-colors", 80 | "Title": "Two Furthest Houses With Different Colors" 81 | }, 82 | { 83 | "QuestionURL": "https://leetcode.com/problems/reverse-words-in-a-string", 84 | "Title": "Reverse Words in a String" 85 | }, 86 | { 87 | "QuestionURL": "https://leetcode.com/problems/earliest-possible-day-of-full-bloom", 88 | "Title": "Earliest Possible Day of Full Bloom" 89 | }, 90 | { 91 | "QuestionURL": "https://leetcode.com/problems/shortest-palindrome", 92 | "Title": "Shortest Palindrome" 93 | }, 94 | { 95 | "QuestionURL": "https://leetcode.com/problems/split-the-array", 96 | "Title": "Split the Array" 97 | }, 98 | { 99 | "QuestionURL": "https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown", 100 | "Title": "Best Time to Buy and Sell Stock with Cooldown" 101 | }, 102 | { 103 | "QuestionURL": "https://leetcode.com/problems/match-alphanumerical-pattern-in-matrix-i", 104 | "Title": "Match Alphanumerical Pattern in Matrix I" 105 | }, 106 | { 107 | "QuestionURL": "https://leetcode.com/problems/maximum-number-of-events-that-can-be-attended", 108 | "Title": "Maximum Number of Events That Can Be Attended" 109 | }, 110 | { 111 | "QuestionURL": "https://leetcode.com/problems/create-target-array-in-the-given-order", 112 | "Title": "Create Target Array in the Given Order" 113 | }, 114 | { 115 | "QuestionURL": "https://leetcode.com/problems/odd-string-difference", 116 | "Title": "Odd String Difference" 117 | }, 118 | { 119 | "QuestionURL": "https://leetcode.com/problems/split-message-based-on-limit", 120 | "Title": "Split Message Based on Limit" 121 | }, 122 | { 123 | "QuestionURL": "https://leetcode.com/problems/find-servers-that-handled-most-number-of-requests", 124 | "Title": "Find Servers That Handled Most Number of Requests" 125 | }, 126 | { 127 | "QuestionURL": "https://leetcode.com/problems/daily-temperatures", 128 | "Title": "Daily Temperatures" 129 | }, 130 | { 131 | "QuestionURL": "https://leetcode.com/problems/rotate-string", 132 | "Title": "Rotate String" 133 | }, 134 | { 135 | "QuestionURL": "https://leetcode.com/problems/walls-and-gates", 136 | "Title": "Walls and Gates" 137 | }, 138 | { 139 | "QuestionURL": "https://leetcode.com/problems/course-schedule", 140 | "Title": "Course Schedule" 141 | }, 142 | { 143 | "QuestionURL": "https://leetcode.com/problems/binary-tree-cameras", 144 | "Title": "Binary Tree Cameras" 145 | }, 146 | { 147 | "QuestionURL": "https://leetcode.com/problems/find-score-of-an-array-after-marking-all-elements", 148 | "Title": "Find Score of an Array After Marking All Elements" 149 | }, 150 | { 151 | "QuestionURL": "https://leetcode.com/problems/reverse-nodes-in-k-group", 152 | "Title": "Reverse Nodes in k-Group" 153 | }, 154 | { 155 | "QuestionURL": "https://leetcode.com/problems/check-if-array-pairs-are-divisible-by-k", 156 | "Title": "Check If Array Pairs Are Divisible by k" 157 | }, 158 | { 159 | "QuestionURL": "https://leetcode.com/problems/spiral-matrix", 160 | "Title": "Spiral Matrix" 161 | }, 162 | { 163 | "QuestionURL": "https://leetcode.com/problems/diameter-of-binary-tree", 164 | "Title": "Diameter of Binary Tree" 165 | }, 166 | { 167 | "QuestionURL": "https://leetcode.com/problems/image-smoother", 168 | "Title": "Image Smoother" 169 | }, 170 | { 171 | "QuestionURL": "https://leetcode.com/problems/rotating-the-box", 172 | "Title": "Rotating the Box" 173 | }, 174 | { 175 | "QuestionURL": "https://leetcode.com/problems/lru-cache", 176 | "Title": "LRU Cache" 177 | }, 178 | { 179 | "QuestionURL": "https://leetcode.com/problems/find-the-length-of-the-longest-common-prefix", 180 | "Title": "Find the Length of the Longest Common Prefix" 181 | }, 182 | { 183 | "QuestionURL": "https://leetcode.com/problems/block-placement-queries", 184 | "Title": "Block Placement Queries" 185 | }, 186 | { 187 | "QuestionURL": "https://leetcode.com/problems/number-of-islands", 188 | "Title": "Number of Islands" 189 | }, 190 | { 191 | "QuestionURL": "https://leetcode.com/problems/palindrome-number", 192 | "Title": "Palindrome Number" 193 | }, 194 | { 195 | "QuestionURL": "https://leetcode.com/problems/second-highest-salary", 196 | "Title": "Second Highest Salary" 197 | }, 198 | { 199 | "QuestionURL": "https://leetcode.com/problems/longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit", 200 | "Title": "Longest Continuous Subarray With Absolute Diff Less Than or Equal to Limit" 201 | }, 202 | { 203 | "QuestionURL": "https://leetcode.com/problems/valid-palindrome", 204 | "Title": "Valid Palindrome" 205 | }, 206 | { 207 | "QuestionURL": "https://leetcode.com/problems/rotate-array", 208 | "Title": "Rotate Array" 209 | }, 210 | { 211 | "QuestionURL": "https://leetcode.com/problems/top-k-frequent-elements", 212 | "Title": "Top K Frequent Elements" 213 | }, 214 | { 215 | "QuestionURL": "https://leetcode.com/problems/word-ladder", 216 | "Title": "Word Ladder" 217 | }, 218 | { 219 | "QuestionURL": "https://leetcode.com/problems/valid-anagram", 220 | "Title": "Valid Anagram" 221 | }, 222 | { 223 | "QuestionURL": "https://leetcode.com/problems/best-time-to-buy-and-sell-stock-iii", 224 | "Title": "Best Time to Buy and Sell Stock III" 225 | }, 226 | { 227 | "QuestionURL": "https://leetcode.com/problems/restore-ip-addresses", 228 | "Title": "Restore IP Addresses" 229 | }, 230 | { 231 | "QuestionURL": "https://leetcode.com/problems/length-of-longest-v-shaped-diagonal-segment", 232 | "Title": "Length of Longest V-Shaped Diagonal Segment" 233 | }, 234 | { 235 | "QuestionURL": "https://leetcode.com/problems/minimum-time-difference", 236 | "Title": "Minimum Time Difference" 237 | }, 238 | { 239 | "QuestionURL": "https://leetcode.com/problems/find-peak-element", 240 | "Title": "Find Peak Element" 241 | }, 242 | { 243 | "QuestionURL": "https://leetcode.com/problems/container-with-most-water", 244 | "Title": "Container With Most Water" 245 | }, 246 | { 247 | "QuestionURL": "https://leetcode.com/problems/k-closest-points-to-origin", 248 | "Title": "K Closest Points to Origin" 249 | }, 250 | { 251 | "QuestionURL": "https://leetcode.com/problems/sliding-window-maximum", 252 | "Title": "Sliding Window Maximum" 253 | }, 254 | { 255 | "QuestionURL": "https://leetcode.com/problems/integer-to-roman", 256 | "Title": "Integer to Roman" 257 | }, 258 | { 259 | "QuestionURL": "https://leetcode.com/problems/candy-crush", 260 | "Title": "Candy Crush" 261 | }, 262 | { 263 | "QuestionURL": "https://leetcode.com/problems/valid-sudoku", 264 | "Title": "Valid Sudoku" 265 | }, 266 | { 267 | "QuestionURL": "https://leetcode.com/problems/simplify-path", 268 | "Title": "Simplify Path" 269 | }, 270 | { 271 | "QuestionURL": "https://leetcode.com/problems/partition-equal-subset-sum", 272 | "Title": "Partition Equal Subset Sum" 273 | }, 274 | { 275 | "QuestionURL": "https://leetcode.com/problems/number-of-adjacent-elements-with-the-same-color", 276 | "Title": "Number of Adjacent Elements With the Same Color" 277 | }, 278 | { 279 | "QuestionURL": "https://leetcode.com/problems/minimum-operations-to-write-the-letter-y-on-a-grid", 280 | "Title": "Minimum Operations to Write the Letter Y on a Grid" 281 | }, 282 | { 283 | "QuestionURL": "https://leetcode.com/problems/reverse-linked-list", 284 | "Title": "Reverse Linked List" 285 | }, 286 | { 287 | "QuestionURL": "https://leetcode.com/problems/number-of-black-blocks", 288 | "Title": "Number of Black Blocks" 289 | }, 290 | { 291 | "QuestionURL": "https://leetcode.com/problems/substrings-of-size-three-with-distinct-characters", 292 | "Title": "Substrings of Size Three with Distinct Characters" 293 | }, 294 | { 295 | "QuestionURL": "https://leetcode.com/problems/merge-intervals", 296 | "Title": "Merge Intervals" 297 | }, 298 | { 299 | "QuestionURL": "https://leetcode.com/problems/largest-number", 300 | "Title": "Largest Number" 301 | }, 302 | { 303 | "QuestionURL": "https://leetcode.com/problems/merge-two-sorted-lists", 304 | "Title": "Merge Two Sorted Lists" 305 | }, 306 | { 307 | "QuestionURL": "https://leetcode.com/problems/number-of-subarrays-that-match-a-pattern-i", 308 | "Title": "Number of Subarrays That Match a Pattern I" 309 | }, 310 | { 311 | "QuestionURL": "https://leetcode.com/problems/house-robber-ii", 312 | "Title": "House Robber II" 313 | }, 314 | { 315 | "QuestionURL": "https://leetcode.com/problems/number-of-matching-subsequences", 316 | "Title": "Number of Matching Subsequences" 317 | }, 318 | { 319 | "QuestionURL": "https://leetcode.com/problems/edit-distance", 320 | "Title": "Edit Distance" 321 | }, 322 | { 323 | "QuestionURL": "https://leetcode.com/problems/brightest-position-on-street", 324 | "Title": "Brightest Position on Street" 325 | }, 326 | { 327 | "QuestionURL": "https://leetcode.com/problems/contains-duplicate", 328 | "Title": "Contains Duplicate" 329 | }, 330 | { 331 | "QuestionURL": "https://leetcode.com/problems/sum-root-to-leaf-numbers", 332 | "Title": "Sum Root to Leaf Numbers" 333 | }, 334 | { 335 | "QuestionURL": "https://leetcode.com/problems/lfu-cache", 336 | "Title": "LFU Cache" 337 | } 338 | ] 339 | -------------------------------------------------------------------------------- /[Premium]305. Number of islands-ii.md: -------------------------------------------------------------------------------- 1 | **Question**: 2 | 3 | You are given an empty 2D binary grid grid of size m x n. The grid represents a map where 0's represent water and 1's represent land. Initially, all the cells of grid are water cells (i.e., all the cells are 0's). 4 | 5 | We may perform an add land operation which turns the water at position into a land. You are given an array positions where positions[i] = [ri, ci] is the position (ri, ci) at which we should operate the ith operation. 6 | 7 | Return an array of integers answer where answer[i] is the number of islands after turning the cell (ri, ci) into a land. 8 | 9 | An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water. 10 | 11 | **Example**. 12 | 13 | ![image](https://github.com/AJAYKR00KJ/LeetCode_Solution/assets/48375037/744cbfdf-da48-470b-9c37-9ef1e4b56fda) 14 | 15 | Input: m = 3, n = 3, positions = [[0,0],[0,1],[1,2],[2,1]] 16 | Output: [1,1,2,3] 17 | Explanation: 18 | Initially, the 2d grid is filled with water. 19 | - Operation #1: addLand(0, 0) turns the water at grid[0][0] into a land. We have 1 island. 20 | - Operation #2: addLand(0, 1) turns the water at grid[0][1] into a land. We still have 1 island. 21 | - Operation #3: addLand(1, 2) turns the water at grid[1][2] into a land. We have 2 islands. 22 | - Operation #4: addLand(2, 1) turns the water at grid[2][1] into a land. We have 3 islands. 23 | 24 | 25 | **Solution: 1**: 26 | 27 | Time Complexity: O(k log(mn)), where k == positions.length 28 | Space Complexity: O(m*n) 29 | 30 | ``` 31 | class Solution { 32 | public: 33 | int getParent(vector &par, int val) { 34 | if(par[val]==val) return par[val]; 35 | return par[val] = getParent(par, par[val]); 36 | } 37 | vector numIslands2(int m, int n, vector>& positions) { 38 | vector par(m*n, -1); 39 | vector ans; 40 | vector> directions = {{-1,0},{0,1}, {1,0}, {0,-1}}; 41 | int islands = 0; 42 | for(vector position: positions) { 43 | int x = position[0], y = position[1], index = x*n + y; 44 | if(par[index]!=-1) { 45 | ans.push_back(islands); 46 | continue; 47 | } 48 | islands++; 49 | par[index] = index; 50 | for(vector direction: directions) { 51 | int nx = x + direction[0], ny = y + direction[1]; 52 | int adjIndex = nx * n + ny; 53 | if(nx>=0 && nx=0 && ny &par, int val) { 80 | if(par[val]==val) return par[val]; 81 | return par[val] = getParent(par, par[val]); 82 | } 83 | void _union(int a, int b, vector &par, vector &rank) { 84 | if(rank[a]rank[b]) { 87 | par[b] = a; 88 | } else { 89 | par[a] = b; 90 | rank[a]++; 91 | } 92 | } 93 | vector numIslands2(int m, int n, vector>& positions) { 94 | vector par(m*n, -1), rank(m*n, 1); 95 | vector ans; 96 | vector> directions = {{-1,0},{0,1}, {1,0}, {0,-1}}; 97 | int islands = 0; 98 | for(vector position: positions) { 99 | int x = position[0], y = position[1], index = x*n + y; 100 | if(par[index]!=-1) { 101 | ans.push_back(islands); 102 | continue; 103 | } 104 | islands++; 105 | par[index] = index; 106 | for(vector direction: directions) { 107 | int nx = x + direction[0], ny = y + direction[1]; 108 | int adjIndex = nx * n + ny; 109 | if(nx>=0 && nx=0 && ny