├── Section 02 - array and vectors ├── arrayProducts.cpp ├── busyLife.cpp ├── fizzBuzzTest.cpp ├── maximumSubarraySum.cpp └── minimumDifference.cpp ├── Section 03 - string problems ├── biggestNumberString.cpp ├── digitalClock.cpp ├── palindromeBreak.cpp ├── runLengthEncoding.cpp ├── stringNormalisation.cpp └── warmUpSearchAll.cpp ├── Section 04 - sliding window ├── countSubarraysWithTargetSum.cpp ├── slidingWindowMaximum.cpp └── smallestDistinctWindow.cpp ├── Section 05 - sorting and searching ├── icpcStandings.cpp ├── jugglingBalls.cpp ├── sortingSubarray.cpp └── stairCaseSearch.cpp ├── Section 06 - binary search ├── gameOfGreed.cpp └── readingBooks.cpp ├── Section 07 - recursion ├── gameOfCoins.cpp ├── gameOfCoinsAdvanced.cpp ├── longestPossibleRoute.cpp ├── moduloExponentiation.cpp ├── nQueen.cpp ├── ratInAMaze.cpp ├── sortedPermutation.cpp └── sudukoSolver.cpp ├── Section 08 - linked list ├── KthLast.cpp ├── detectCycleInALinkedList.cpp ├── middleElement.cpp └── warmUpSearch.cpp ├── Section 09 - stacks and queue ├── firstNonRepeatingCharacter.cpp ├── simplifyPath.cpp └── stockSpan.cpp ├── Section 10 - binary trees ├── leftView.cpp ├── siblingsSwap.cpp └── sortedNodesAtDistanceK.cpp ├── Section 11 - binary search tree ├── LCA.cpp ├── isBST.cpp ├── shortestTreePath.cpp ├── speacialBST.cpp └── warmUpBstSearch.cpp ├── Section 12 - priority queue ├── mergeKSorterdArrays.cpp └── runningMeadianClass.cpp ├── Section 13 - hashing ├── breakTheChain.cpp ├── groupAnagrams.cpp ├── longestKSumSubarray.cpp ├── minimumBars.cpp ├── warmUp-firstRepeatingLetter.cpp └── warmUpCommonElements.cpp ├── Section 14 - tries and pattern ├── minimumXorPair.cpp ├── phoneNumberSearch.cpp └── prateekBhayia&GooglyStrings.cpp ├── Section 15 - graphs ├── astranautPairs.cpp ├── cycleDetection1UndirectedGraph.cpp ├── cycleDetection2DirectedGraph.cpp ├── graphSequence.cpp ├── largestIsland.cpp ├── shortestGridPath.cpp └── snakes&LadderGames.cpp ├── Section 16 - dp 1D └── frogJump2atCoder.cpp └── Section 17 - dp 2D ├── coinChange2.cpp ├── editDistance.cpp ├── gameOfWits.cpp ├── mixturesSpoj.cpp ├── palindromicPartitioning.cpp └── wildcardPatternMatching.cpp /Section 02 - array and vectors/arrayProducts.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | //Expected Complexity O(N) 5 | vector productArray(vector arr){ 6 | int n = arr.size(); 7 | // Base case 8 | if (n == 1) { 9 | return {0}; 10 | } 11 | 12 | int i, temp = 1; 13 | 14 | vector prod(n,1); 15 | /* In this loop, temp variable contains product of 16 | elements on left side excluding arr[i] */ 17 | for (i = 0; i < n; i++) { 18 | prod[i] = temp; 19 | temp *= arr[i]; 20 | } 21 | 22 | /* Initialize temp to 1 23 | for product on right side */ 24 | temp = 1; 25 | 26 | /* In this loop, temp variable contains product of 27 | elements on right side excluding arr[i] */ 28 | for (i = n - 1; i >= 0; i--) { 29 | prod[i] *= temp; 30 | temp *= arr[i]; 31 | } 32 | return prod; 33 | } -------------------------------------------------------------------------------- /Section 02 - array and vectors/busyLife.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | bool compare(pair v1, pair v2){ 6 | return v1.second < v2.second; 7 | } 8 | 9 | 10 | int countActivites(vector > v){ 11 | //Complete this method 12 | 13 | sort(v.begin(),v.end(),compare); 14 | int count = 1; 15 | int finish = v[0].second; 16 | 17 | for(int i=1;i=finish){ 19 | count++; 20 | finish = v[i].second; 21 | } 22 | } 23 | return count; 24 | } -------------------------------------------------------------------------------- /Section 02 - array and vectors/fizzBuzzTest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | 6 | vector fizzbuzz(int n){ 7 | //Complete this method 8 | vector result; 9 | for(int i=1;i<=n;i++){ 10 | if((i%15)==0){ 11 | result.push_back("FizzBuzz"); 12 | } 13 | else if(i%5 == 0){ 14 | result.push_back("Buzz"); 15 | } 16 | else if(i%3 == 0){ 17 | result.push_back("Fizz"); 18 | } 19 | else{ 20 | result.push_back(to_string(i)); 21 | } 22 | 23 | } 24 | 25 | return result; 26 | } -------------------------------------------------------------------------------- /Section 02 - array and vectors/maximumSubarraySum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int maxSubarraySum(vector arr){ 5 | //Complete this function, your function should return the maximum subarray sum 6 | int n = arr.size(); 7 | int cs = 0; 8 | int ms = 0; 9 | 10 | for(int i=0;i 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | 7 | pair minDifference(vector a1,vector a2){ 8 | //Complete this method 9 | // Write your code here. 10 | sort(a2.begin(),a2.end()); 11 | vector result; 12 | //iterate over 1 and do binary search 13 | int p1,p2; 14 | 15 | int diff = INT_MAX; 16 | 17 | for(int x : a1){ 18 | auto lb = lower_bound(a2.begin(),a2.end(),x) - a2.begin(); 19 | 20 | if(lb>=1 and x - a2[lb-1] < diff){ 21 | diff = x - a2[lb-1]; 22 | p2 = a2[lb-1]; 23 | p1 = x; 24 | } 25 | 26 | if(lb!=a2.size() and a2[lb]-x < diff ){ 27 | diff = a2[lb] - x; 28 | p1 = x; 29 | p2 = a2[lb]; 30 | } 31 | } 32 | 33 | return {p1,p2}; 34 | } -------------------------------------------------------------------------------- /Section 03 - string problems/biggestNumberString.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | bool compare(string s1,string s2){ 5 | return s1 + s2 > s2 + s1; 6 | } 7 | 8 | string concatenate(vector numbers){ 9 | vector output; 10 | 11 | for(int no:numbers){ 12 | output.push_back(to_string(no)); 13 | } 14 | sort(output.begin(),output.end(),compare); 15 | 16 | string ans = ""; 17 | for(string x:output){ 18 | ans += x; 19 | } 20 | return ans; 21 | } -------------------------------------------------------------------------------- /Section 03 - string problems/digitalClock.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | string convert_to_digital_time(int mins){ 5 | int hours = mins/60; 6 | int minutes = mins%60; 7 | string hrs_s = to_string(hours); 8 | string min_s = minutes < 10 ? "0" + to_string(minutes) : to_string(minutes); 9 | return hrs_s + ":" + min_s; 10 | } 11 | -------------------------------------------------------------------------------- /Section 03 - string problems/palindromeBreak.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | string breakPalindrome(string palindrome) { 5 | //If we have string size == 1, return "". Since any replacement cannot break the palindrome. 6 | if(palindrome.size() == 1) 7 | return ""; 8 | 9 | vector> count(26); 10 | int firstNonA = -1; 11 | 12 | for(int i = 0; i < palindrome.size(); i++) 13 | { 14 | count[palindrome[i] - 'a'].push_back(i); 15 | 16 | //Update firstNonA index if its not yet found. 17 | if(firstNonA == -1 && palindrome[i] != 'a') 18 | firstNonA = i; 19 | } 20 | 21 | //If we have N-1 a's, we need to replace last a with b 22 | if(count[0].size() >= palindrome.size() - 1) 23 | palindrome[count[0].back()] = 'b'; 24 | //Else replace first non-'a' character with 'a' 25 | else 26 | palindrome[firstNonA] = 'a'; 27 | 28 | return palindrome; 29 | } -------------------------------------------------------------------------------- /Section 03 - string problems/runLengthEncoding.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | //str is the input the string 5 | string compressString(const string &str){ 6 | int n = str.length(); 7 | string output; 8 | for (int i = 0; i < n; i++) { 9 | 10 | // Count occurrences of current character 11 | int count = 1; 12 | 13 | while (i < n - 1 && str[i] == str[i + 1]) { 14 | count++; 15 | i++; 16 | } 17 | 18 | // Store the Character and its count 19 | output += str[i]; 20 | output += to_string(count); 21 | } 22 | if(output.length()>str.length()){ 23 | return str; 24 | } 25 | return output; 26 | } -------------------------------------------------------------------------------- /Section 03 - string problems/stringNormalisation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int skip_whitespace(const string &sentence, int idx) { 5 | while (idx < sentence.length() && sentence[idx] == ' ') { 6 | idx += 1; 7 | } 8 | 9 | return idx; 10 | } 11 | 12 | int normalize_word(string &sentence, int idx) { 13 | if (idx < sentence.length() && sentence[idx] != ' ') { 14 | sentence[idx] = toupper(sentence[idx]); 15 | idx += 1; 16 | } 17 | 18 | while (idx < sentence.length() && sentence[idx] != ' ') { 19 | sentence[idx] = tolower(sentence[idx]); 20 | idx += 1; 21 | } 22 | 23 | return idx; 24 | } 25 | 26 | string normalize(const string &sentence) { 27 | string copy = sentence; 28 | int idx = 0; 29 | 30 | while (idx < copy.length()) { 31 | idx = skip_whitespace(copy, idx); 32 | idx = normalize_word(copy, idx); 33 | } 34 | 35 | return copy; 36 | } -------------------------------------------------------------------------------- /Section 03 - string problems/warmUpSearchAll.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | vector stringSearch(string big,string small){ 5 | 6 | vector result; 7 | int index = big.find(small); 8 | while(index!=-1){ 9 | result.push_back(index); 10 | index = big.find(small,index+1); 11 | } 12 | 13 | return result; 14 | } 15 | -------------------------------------------------------------------------------- /Section 04 - sliding window/countSubarraysWithTargetSum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | int cntSubarrays(vectorarr,int sum){ 6 | //complete this method 7 | unordered_map prevSum; 8 | int n = arr.size(); 9 | int res = 0; 10 | 11 | // Sum of elements so far. 12 | int currsum = 0; 13 | 14 | for (int i = 0; i < n; i++) { 15 | 16 | // Add current element to sum so far. 17 | currsum += arr[i]; 18 | 19 | // If currsum is equal to desired sum, 20 | // then a new subarray is found. So 21 | // increase count of subarrays. 22 | if (currsum == sum) 23 | res++; 24 | 25 | // currsum exceeds given sum by currsum 26 | // - sum. Find number of subarrays having 27 | // this sum and exclude those subarrays 28 | // from currsum by increasing count by 29 | // same amount. 30 | if (prevSum.find(currsum - sum) != prevSum.end()) 31 | res += (prevSum[currsum - sum]); 32 | 33 | // Add currsum value to count of 34 | // different values of sum. 35 | prevSum[currsum]++; 36 | } 37 | 38 | return res; 39 | } -------------------------------------------------------------------------------- /Section 04 - sliding window/slidingWindowMaximum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | vector maxInWindow(vector a,int k){ 6 | 7 | //Algorithm 8 | vector output; 9 | int n = a.size(); 10 | 11 | deque Q(k); 12 | //1. Process only the first K elements 13 | int i; 14 | 15 | for(i=0;i a[Q.back()]){ 19 | Q.pop_back(); 20 | } 21 | 22 | Q.push_back(i); 23 | 24 | } 25 | 26 | //2. Remaining the elements of the array 27 | for( ;i= a[Q.back()]){ 36 | Q.pop_back(); 37 | } 38 | 39 | //always 40 | Q.push_back(i); 41 | } 42 | 43 | 44 | output.push_back(a[Q.front()]); 45 | return output; 46 | 47 | } -------------------------------------------------------------------------------- /Section 04 - sliding window/smallestDistinctWindow.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | const int MAX_CHARS = 256; 6 | 7 | //Algorithm : https://www.geeksforgeeks.org/smallest-window-contains-characters-string/#:~:text=Solution%3A%20Above%20problem%20states%20that,the%20characters%20is%20%E2%80%9Cabcbcd%E2%80%9D. 8 | 9 | // Function to find smallest window containing 10 | // all distinct characters 11 | string smallestWindow(string str) 12 | { 13 | int n = str.length(); 14 | if(n==0){ 15 | return ""; 16 | } 17 | 18 | // Count all distinct characters. 19 | int dist_count = 0; 20 | bool visited[MAX_CHARS] = { false }; 21 | 22 | for (int i = 0; i < n; i++) { 23 | if (visited[str[i]] == false) { 24 | visited[str[i]] = true; 25 | dist_count++; 26 | } 27 | } 28 | 29 | // We basically maintain a window of characters 30 | // that contains all characters of given string. 31 | int start = 0, start_index = -1, min_len = INT_MAX; 32 | 33 | int count = 0; 34 | int curr_count[MAX_CHARS] = { 0 }; 35 | for (int j = 0; j < n; j++) { 36 | // Count occurrence of characters of string 37 | curr_count[str[j]]++; 38 | 39 | // If any distinct character matched, 40 | // then increment count 41 | if (curr_count[str[j]] == 1) 42 | count++; 43 | 44 | // if all the characters are matched 45 | if (count == dist_count) { 46 | // Try to minimize the window i.e., check if 47 | // any character is occurring more no. of times 48 | // than its occurrence in pattern, if yes 49 | // then remove it from starting and also remove 50 | // the useless characters. 51 | while (curr_count[str[start]] > 1) { 52 | if (curr_count[str[start]] > 1) 53 | curr_count[str[start]]--; 54 | start++; 55 | } 56 | 57 | // Update window size 58 | int len_window = j - start + 1; 59 | if (min_len > len_window) { 60 | min_len = len_window; 61 | start_index = start; 62 | } 63 | } 64 | } 65 | 66 | // Return substring starting from start_index 67 | // and length min_len 68 | return str.substr(start_index, min_len); 69 | } -------------------------------------------------------------------------------- /Section 05 - sorting and searching/icpcStandings.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int badness(vector > teams){ 5 | //Complete this function to return the min badness 6 | int n = teams.size(); 7 | //create a count array init with 0 8 | vector cnt(n+1,0); 9 | 10 | 11 | for(int i=0;i 2 | using namespace std; 3 | 4 | 5 | vector sortBalls(vector a){ 6 | //sort the balls in place 7 | int n = a.size(); 8 | 9 | int s = 0; 10 | int e = n-1; 11 | int mid = 0; 12 | 13 | while(mid<=e){ 14 | if(a[mid] == 0){ 15 | swap(a[s++],a[mid++]); 16 | } 17 | else if(a[mid] == 1){ 18 | mid++; 19 | } 20 | else{ 21 | swap(a[mid],a[e--]); 22 | } 23 | } 24 | return a; 25 | } -------------------------------------------------------------------------------- /Section 05 - sorting and searching/sortingSubarray.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | //This is O(NLogN) Solution, O(N) Solution also exists 6 | pair subarraySorting(vector a) { 7 | 8 | vector b(a); 9 | sort(a.begin(),a.end()); 10 | 11 | //do comparison 12 | int i = 0; 13 | int n = a.size(); 14 | while(i=0 and a[j]==b[j]){ 19 | j--; 20 | } 21 | //already sorted 22 | if(i==a.size()){ 23 | return {-1,-1}; 24 | } 25 | return {i,j}; 26 | } -------------------------------------------------------------------------------- /Section 05 - sorting and searching/stairCaseSearch.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | pair search(int m, int n, vector> v, int k){ 6 | int i=m-1; 7 | int j=0; 8 | while(j=0){ 9 | if(v[i][j]==k){ 10 | break; 11 | } 12 | else if(v[i][j] p={i,j}; 20 | return p; 21 | } -------------------------------------------------------------------------------- /Section 06 - binary search/gameOfGreed.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | bool divideAmongK(vector arr,int n,int k,int limit){ 5 | //return true if every partition gets atleast limit no of coins 6 | 7 | int cnt = 0; 8 | int current_sum = 0; 9 | 10 | for(int i=0;i=limit){ 12 | cnt +=1; 13 | current_sum = 0; 14 | } 15 | else{ 16 | current_sum += arr[i]; 17 | } 18 | } 19 | 20 | return cnt>=k; 21 | } 22 | 23 | int getCoins(vector arr,int k){ 24 | //return the minimum number 25 | int n = arr.size(); 26 | int e = 0; 27 | int s = 0; 28 | for(int i=0;i 2 | using namespace std; 3 | 4 | bool isPossible(vector &books,int m,int mid){ 5 | 6 | int n = books.size(); 7 | int cs = 0; 8 | int students = 1; 9 | 10 | for(int i = 0; i < n; i++){ 11 | 12 | if(cs + books[i] > mid){ 13 | students++; 14 | cs = books[i]; 15 | 16 | if(students > m){ 17 | return false; 18 | } 19 | } 20 | else{ 21 | cs += books[i]; 22 | } 23 | } 24 | 25 | return true; 26 | } 27 | 28 | 29 | int minPages(vector books, int m){ 30 | int n = books.size(); 31 | //complete this code 32 | int end = 0; 33 | int start = 0; 34 | 35 | for(int b:books){ 36 | end += b; 37 | start = max(start,b); 38 | } 39 | int result = INT_MAX; 40 | 41 | while(start<=end){ 42 | int mid = (start + end)/2; 43 | if(isPossible(books,m,mid)){ 44 | result = min(result,mid); 45 | end = mid - 1; 46 | } 47 | 48 | else{ 49 | start = mid + 1; 50 | } 51 | } 52 | return result; 53 | } -------------------------------------------------------------------------------- /Section 07 - recursion/gameOfCoins.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int game(int n, vector v, int s, int e){ 5 | 6 | if(s==e || s==e-1){ 7 | return max(v[s],v[e]); 8 | } 9 | 10 | int op1=v[s] + min(game(n,v,s+2,e),game(n,v,s+1,e-1)); 11 | int op2=v[e] + min(game(n,v,s+1,e-1),game(n,v,s,e-2)); 12 | return max(op1,op2); 13 | } 14 | 15 | int MaxValue(int n, vector v){ 16 | int res=game(n,v,0,n-1); 17 | return res; 18 | } -------------------------------------------------------------------------------- /Section 07 - recursion/gameOfCoinsAdvanced.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int sum(vector v, int i, int j) 5 | { 6 | int res = 0; 7 | for (int k = i; k < j; k++) res += v[k]; 8 | return res; 9 | } 10 | 11 | int calc(vector v, int s, int e, int k) 12 | { 13 | if (e - s + 1 < 0) 14 | { 15 | return 0; 16 | } 17 | 18 | int res = INT_MIN; 19 | for (int i = 0; i <= k; i++) 20 | { 21 | int ans = sum(v, s, s + i) + sum(v, e - k + i + 1, e + 1); 22 | int op = INT_MAX; 23 | for (int j = 0; j <= k; j++) 24 | { 25 | op = min(op, calc(v, s + i + j, e - k + i - k + j, k)); 26 | } 27 | res = max(res, ans + op); 28 | } 29 | 30 | return res; 31 | } 32 | int MaxValue(int n, vector v, int k){ 33 | int res=calc(v,0,n-1,k); 34 | return res; 35 | } 36 | -------------------------------------------------------------------------------- /Section 07 - recursion/longestPossibleRoute.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | pair findPath(int m,int n, int i, int j, vector> v, bool mat[][100]){ 5 | if(i==m-1 && j==n-1){ 6 | 7 | pair p={true,0}; 8 | return p; 9 | } 10 | if(i>=m || i<0 || j>=n || j<0 ){ 11 | 12 | pair p={false,-1}; 13 | return p; 14 | } 15 | else{ 16 | 17 | mat[i][j]=true; 18 | pair res={false,-1}; 19 | 20 | if(i p1=findPath(m,n,i+1,j,v,mat); 22 | if(p1.first){ 23 | res.first=true; 24 | res.second=max(res.second,p1.second); 25 | } 26 | } 27 | if(j p2=findPath(m,n,i,j+1,v,mat); 29 | if(p2.first){ 30 | res.first=true; 31 | res.second=max(res.second,p2.second); 32 | } 33 | } 34 | if(i>0 && v[i-1][j]==1 && mat[i-1][j]==false){ 35 | pair p3=findPath(m,n,i-1,j,v,mat); 36 | if(p3.first){ 37 | res.first=true; 38 | res.second=max(res.second,p3.second); 39 | } 40 | } 41 | if(j>0 && v[i][j-1]==1 && mat[i][j-1]==false){ 42 | pair p4=findPath(m,n,i,j-1,v,mat); 43 | if(p4.first){ 44 | res.first=true; 45 | res.second=max(res.second,p4.second); 46 | } 47 | } 48 | mat[i][j]=false; 49 | res.second+=1; 50 | return res; 51 | } 52 | } 53 | 54 | 55 | int findLongestPath(int m, int n, vector> v){ 56 | bool mat[100][100]={{0}}; 57 | 58 | pair p=findPath(m,n,0,0,v,mat); 59 | return p.second; 60 | } 61 | -------------------------------------------------------------------------------- /Section 07 - recursion/moduloExponentiation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | long long int solve(int A, int B, long C) 5 | { 6 | if (A==0) return 0; 7 | if (B==0) return 1; 8 | 9 | long long int y; 10 | if (B&1) 11 | { 12 | y = A % C; 13 | y = (y * solve(A, B - 1, C) % C) % C; 14 | } 15 | 16 | else 17 | { 18 | y = solve(A, B / 2, C); 19 | y = (y * y) % C; 20 | } 21 | 22 | return (long long int)((y + C) % C); 23 | } 24 | long long int powerModulo(int a, int b) 25 | { 26 | long mod = 1e9+7; 27 | return solve(a, b, mod); 28 | } 29 | -------------------------------------------------------------------------------- /Section 07 - recursion/nQueen.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | int cnt; 6 | 7 | int isSafe(int N, int mat[][20], int r, int c) 8 | { 9 | // return 0 if two queens share the same column 10 | for (int i = 0; i < r; i++) 11 | { 12 | if (mat[i][c] == 1) { 13 | return 0; 14 | } 15 | } 16 | 17 | // return 0 if two queens share the same `` diagonal 18 | for (int i = r, j = c; i >= 0 && j >= 0; i--, j--) 19 | { 20 | if (mat[i][j] == 1) { 21 | return 0; 22 | } 23 | } 24 | 25 | // return 0 if two queens share the same `/` diagonal 26 | for (int i = r, j = c; i >= 0 && j < N; i--, j++) 27 | { 28 | if (mat[i][j] == 1) { 29 | return 0; 30 | } 31 | } 32 | 33 | return 1; 34 | } 35 | 36 | void solve(int N,int mat[][20], int r) 37 | { 38 | // if `N` queens are placed successfully, print the solution 39 | if (r == N) 40 | { 41 | cnt++; 42 | return; 43 | } 44 | 45 | // place queen at every square in the current row `r` 46 | // and recur for each valid movement 47 | for (int i = 0; i < N; i++) 48 | { 49 | // if no two queens threaten each other 50 | if (isSafe(N, mat, r, i)) 51 | { 52 | // place queen on the current square 53 | mat[r][i] = 1; 54 | 55 | // recur for the next row 56 | solve(N,mat, r + 1); 57 | 58 | // backtrack and remove the queen from the current square 59 | mat[r][i] = 0; 60 | } 61 | } 62 | } 63 | 64 | 65 | int nQueen(int n){ 66 | cnt =0; 67 | int arr[20][20]={0}; 68 | 69 | solve(n,arr,0); 70 | return cnt; 71 | 72 | } 73 | 74 | -------------------------------------------------------------------------------- /Section 07 - recursion/ratInAMaze.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | bool calc(int n, vector> c, vector &v, int i = 0, int j = 0) 7 | { 8 | if(i==n && j==n) return true; 9 | if(i==n+1 || j==n+1) return false; 10 | 11 | if(j != n && c[i][j+1] != 'X') 12 | { 13 | if(calc(n, c, v, i, j+1)) 14 | { 15 | v.push_back( (i)*(n+1) + j+2 ); 16 | return true; 17 | } 18 | } 19 | 20 | if(i != n && c[i+1][j] != 'X') 21 | { 22 | if(calc(n, c, v, i+1, j)) 23 | { 24 | v.push_back( (i+1)*(n+1) + j+1 ); 25 | return true; 26 | } 27 | } 28 | 29 | return false; 30 | } 31 | 32 | vector findPath(int n, vector> c) 33 | { 34 | vector v; 35 | calc(n-1,c,v); 36 | v.push_back(1); 37 | reverse(v.begin(), v.end()); 38 | return v; 39 | } -------------------------------------------------------------------------------- /Section 07 - recursion/sortedPermutation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | vector v; 4 | 5 | void find_Permutations(char *inp, int i){ 6 | if(inp[i]=='\0'){ 7 | string str(inp); 8 | v.push_back(str); 9 | return; 10 | } 11 | for(int j=i; inp[j]!=0; j++){ 12 | swap(inp[i],inp[j]); 13 | find_Permutations(inp,i+1); 14 | swap(inp[i],inp[j]); 15 | } 16 | 17 | } 18 | 19 | vector findSortedPermutations(string s){ 20 | v.clear(); 21 | int n=s.length(); 22 | char inp[n+1]; 23 | for(int i=0; i st; 30 | for(int i=0; i 2 | using namespace std; 3 | 4 | //helper function 2 5 | bool safe(vector> v, int i, int j, int num){ 6 | for (int x=0; x<9; x++) 7 | { 8 | if(v[x][j]==num || v[i][x]==num) 9 | return false; 10 | } 11 | 12 | for(int m = (i/3)*3; m < ((i/3)*3)+3; m++) 13 | { 14 | for(int n = (j/3)*3; n < ((j/3)*3)+3; n++) 15 | { 16 | if(v[m][n] == num) 17 | return false; 18 | } 19 | } 20 | return true; 21 | 22 | } 23 | //helper function 1 24 | bool solve(vector> &v, int i, int j){ 25 | //base case 26 | if(i==9){ 27 | return true; 28 | } 29 | //recursive case 1 30 | else if(j==9){ 31 | return solve(v,i+1,0); 32 | } 33 | //recursive case 2 34 | else if(v[i][j]==0){ 35 | for(int num=1; num<=9; num++){ 36 | if(safe(v,i,j,num)){ 37 | v[i][j]=num; 38 | if(solve(v,i,j+1)){ 39 | return true; 40 | } 41 | } 42 | } 43 | v[i][j]=0; 44 | return false; 45 | } 46 | //recursive case 3 47 | else{ 48 | return solve(v,i,j+1); 49 | } 50 | 51 | } 52 | 53 | //template function 54 | vector > solveSudoku(vector> input){ 55 | 56 | solve(input, 0,0); 57 | return input; 58 | 59 | } -------------------------------------------------------------------------------- /Section 08 - linked list/KthLast.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | class node{ 6 | public: 7 | int data; 8 | node* next; 9 | 10 | node(int data){ 11 | this->data = data; 12 | next = NULL; 13 | } 14 | }; 15 | 16 | int kthLastElement(node * head,int k){ 17 | //Complete this function to return kth last element 18 | node * fast = head; 19 | node * slow = head; 20 | 21 | int cnt = 0; 22 | while(cnt < k){ 23 | fast = fast->next; 24 | cnt++; 25 | } 26 | 27 | while(fast!=NULL){ 28 | slow = slow->next; 29 | fast = fast->next; 30 | } 31 | 32 | return slow->data; 33 | } -------------------------------------------------------------------------------- /Section 08 - linked list/detectCycleInALinkedList.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | class node{ 6 | public: 7 | int data; 8 | node* next; 9 | 10 | node(int data){ 11 | this->data = data; 12 | next = NULL; 13 | } 14 | }; 15 | 16 | bool containsCycle(node *head){ 17 | //Complete this function 18 | 19 | node*slow = head; 20 | node*fast = head; 21 | 22 | while(slow and fast and fast->next){ 23 | slow = slow->next; 24 | fast = fast->next->next; 25 | if(slow==fast){ 26 | return true; 27 | } 28 | } 29 | return false; 30 | } -------------------------------------------------------------------------------- /Section 08 - linked list/middleElement.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | class node{ 6 | public: 7 | int data; 8 | node* next; 9 | 10 | node(int data){ 11 | this->data = data; 12 | next = NULL; 13 | } 14 | }; 15 | 16 | int getMid(node * head){ 17 | //Complete this function to return kth last element 18 | node * fast = head->next; 19 | node * slow = head; 20 | 21 | while(fast and fast->next){ 22 | fast = fast->next->next; 23 | slow = slow->next; 24 | } 25 | 26 | return slow->data; 27 | } -------------------------------------------------------------------------------- /Section 08 - linked list/warmUpSearch.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | class node{ 6 | public: 7 | int data; 8 | node* next; 9 | 10 | node(int data){ 11 | this->data = data; 12 | next = NULL; 13 | } 14 | }; 15 | 16 | 17 | bool isPresent(node * head, int key){ 18 | //Complete this function to return kth last element 19 | 20 | node * temp = head; 21 | while(temp!=NULL){ 22 | if(temp->data==key){ 23 | return true; 24 | } 25 | temp = temp->next; 26 | } 27 | 28 | return false; 29 | } -------------------------------------------------------------------------------- /Section 09 - stacks and queue/firstNonRepeatingCharacter.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | vector FindFirstNonRepeatingCharacter(string s){ 6 | queue q; 7 | int freq[26]={0}; 8 | vector res; 9 | for(int i=0; i1){ 14 | q.pop(); 15 | } 16 | else{ 17 | res.push_back(q.front()); 18 | break; 19 | } 20 | } 21 | if(q.empty()){ 22 | res.push_back('0'); 23 | } 24 | } 25 | return res; 26 | 27 | } -------------------------------------------------------------------------------- /Section 09 - stacks and queue/simplifyPath.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | 7 | string simplifyPath(string path){ 8 | istringstream iss(path); 9 | 10 | string token; 11 | vector tokens; 12 | bool rootdir = path[0]=='/'; 13 | 14 | while(getline(iss,token,'/')){ 15 | if(token!="." and token!=""){ 16 | tokens.push_back(token); 17 | } 18 | } 19 | 20 | 21 | //--------------------// 22 | vector stack; 23 | 24 | if(path[0]=='/'){ 25 | stack.push_back(""); 26 | } 27 | 28 | for(string token:tokens){ 29 | if(token==".."){ 30 | //pop back prev 31 | if(stack.size()==0 or stack[stack.size()-1]==".."){ 32 | stack.push_back(token); 33 | } 34 | // checkingthis condition, pop back previous except root '/' when current is '.' 35 | else if(stack[stack.size()-1]!=""){ 36 | stack.pop_back(); 37 | } 38 | } 39 | else{ 40 | stack.push_back(token); 41 | } 42 | } 43 | 44 | //corner case 45 | if(stack.size()==1 and stack[0]==""){ 46 | return "/"; 47 | } 48 | 49 | //otherwise construct the string 50 | ostringstream oss; 51 | int i = 0; 52 | for(auto token : stack){ 53 | 54 | if(i!=0){ 55 | oss<<"/"; 56 | } 57 | 58 | i++; 59 | oss << token; 60 | } 61 | 62 | return oss.str(); 63 | } -------------------------------------------------------------------------------- /Section 09 - stacks and queue/stockSpan.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | vector stockSpan(vector v) { 4 | int n = v.size(); 5 | stack s; 6 | vector vec(n, 1); 7 | vec[0] = 1; 8 | s.push(0); 9 | for (int i = 1; i < n; i++) { 10 | while (!s.empty() and v[s.top()] <= v[i]) { 11 | s.pop(); 12 | } 13 | if (!s.empty()) { 14 | vec[i] = i - s.top(); 15 | } 16 | else vec[i] = i + 1; 17 | s.push(i); 18 | } 19 | 20 | return vec; 21 | } 22 | -------------------------------------------------------------------------------- /Section 10 - binary trees/leftView.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Node 5 | { 6 | public: 7 | int key; 8 | Node *left; 9 | Node *right; 10 | 11 | Node(int key){ 12 | this->key = key; 13 | left = right = NULL; 14 | } 15 | }; 16 | 17 | 18 | 19 | int max_level = 0; 20 | void leftViewUtil(vector& vec, Node* root, int level) 21 | { 22 | // base case 23 | if (root == NULL) 24 | return; 25 | 26 | // If this is the first node of its level 27 | if (max_level < level) { 28 | vec.push_back(root->key); 29 | max_level = level; 30 | } 31 | 32 | // Recur for left and right subtrees 33 | leftViewUtil(vec, root->left, level + 1); 34 | leftViewUtil(vec, root->right, level + 1); 35 | } 36 | 37 | // Function to get the left view 38 | vector leftView(Node* root) 39 | { 40 | max_level = 0; // initialise max_level with 0 here 41 | vector vec; 42 | // calling util function 43 | leftViewUtil(vec, root, 1); 44 | return vec; 45 | } -------------------------------------------------------------------------------- /Section 10 - binary trees/siblingsSwap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Node 5 | { 6 | public: 7 | int key; 8 | Node *left; 9 | Node *right; 10 | 11 | Node(int key){ 12 | this->key = key; 13 | left = right = NULL; 14 | } 15 | }; 16 | 17 | 18 | bool equal(Node * X, Node * Y){ 19 | //Complete the Function 20 | if (X == Y) { 21 | return true; 22 | } 23 | return (X && Y) && (X->key == Y->key) && 24 | ((equal(X->left, Y->left) && equal(X->right, Y->right)) || 25 | (equal(X->right, Y->left) && equal(X->left, Y->right))); 26 | 27 | } -------------------------------------------------------------------------------- /Section 10 - binary trees/sortedNodesAtDistanceK.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | class node{ 6 | 7 | public: 8 | int data; 9 | node*left; 10 | node*right; 11 | 12 | node(int d){ 13 | data = d; 14 | left = NULL; 15 | right = NULL; 16 | } 17 | }; 18 | 19 | 20 | void printAtLevelK(vector &v, node*root, int k){ 21 | if(root==NULL){ 22 | return; 23 | } 24 | if(k==0){ 25 | v.push_back(root->data); 26 | return; 27 | } 28 | printAtLevelK(v,root->left,k-1); 29 | printAtLevelK(v,root->right,k-1); 30 | return; 31 | } 32 | 33 | 34 | int printNodesAtDistanceK(vector &v, node* root, node* target,int k){ 35 | 36 | //base case 37 | if(root==NULL){ 38 | return -1; 39 | } 40 | 41 | //reach the target node 42 | if(root==target){ 43 | printAtLevelK(v,target,k); 44 | return 0; 45 | } 46 | 47 | 48 | //other case 49 | int DL = printNodesAtDistanceK(v,root->left,target,k); 50 | if(DL!=-1){ 51 | 52 | //2 cases 53 | // Print the current node 54 | if(DL + 1 ==k){ 55 | v.push_back(root->data); 56 | } 57 | // or print somenodes in the rightsubtree 58 | else{ 59 | printAtLevelK(v,root->right,k-2-DL); 60 | } 61 | return 1 + DL; 62 | } 63 | int DR = printNodesAtDistanceK(v,root->right,target,k); 64 | if(DR!=-1){ 65 | //2 cases 66 | //print current node 67 | if(DR + 1 ==k){ 68 | v.push_back(root->data); 69 | } 70 | else{ 71 | printAtLevelK(v,root->left,k-2-DR); 72 | } 73 | return 1 + DR; 74 | } 75 | return -1; 76 | } 77 | 78 | vector nodesAtDistanceK(node *root, node *target, int k){ 79 | //return a SORTED vector of the nodes 80 | 81 | vector result; 82 | printNodesAtDistanceK(result, root, target,k); 83 | sort(result.begin(),result.end()); 84 | return result; 85 | 86 | } -------------------------------------------------------------------------------- /Section 11 - binary search tree/LCA.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | class node { 6 | public: 7 | int data; 8 | node*left; 9 | node*right; 10 | 11 | node(int d) { 12 | data = d; 13 | left = NULL; 14 | right = NULL; 15 | } 16 | }; 17 | 18 | 19 | node* lca(node*root, int a, int b) { 20 | 21 | 22 | if (root == NULL) { 23 | return NULL; 24 | } 25 | 26 | if (root->data == a or root->data == b) { 27 | return root; 28 | } 29 | 30 | //search in left and right subtrees 31 | node * leftans = lca(root->left, a, b); 32 | node* rightans = lca(root->right, a, b); 33 | 34 | if (leftans != NULL and rightans != NULL) { 35 | return root; 36 | } 37 | 38 | if (leftans != NULL) { 39 | return leftans; 40 | } 41 | return rightans; 42 | } -------------------------------------------------------------------------------- /Section 11 - binary search tree/isBST.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Node 5 | { 6 | public: 7 | int key; 8 | Node *left; 9 | Node *right; 10 | 11 | Node(int key){ 12 | this->key = key; 13 | left = right = NULL; 14 | } 15 | }; 16 | 17 | bool isBSTUtil(Node* node, int min, int max) 18 | { 19 | /* an empty tree is BST */ 20 | if (node==NULL) 21 | return true; 22 | 23 | /* false if this node violates 24 | the min/max constraint */ 25 | if (node->key < min || node->key > max) 26 | return false; 27 | 28 | /* otherwise check the subtrees recursively, 29 | tightening the min or max constraint */ 30 | return 31 | isBSTUtil(node->left, min, node->key) && 32 | isBSTUtil(node->right, node->key, max); 33 | } 34 | 35 | bool isBST(Node * root){ 36 | //complete this method 37 | return isBSTUtil(root, INT_MIN,INT_MAX); 38 | 39 | } -------------------------------------------------------------------------------- /Section 11 - binary search tree/shortestTreePath.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class node 5 | { 6 | public: 7 | int key; 8 | node *left; 9 | node *right; 10 | 11 | node(int key){ 12 | this->key = key; 13 | left = right = NULL; 14 | } 15 | }; 16 | 17 | node* lca(node*root, int a, int b) { 18 | 19 | 20 | if (root == NULL) { 21 | return NULL; 22 | } 23 | 24 | if (root->key == a or root->key == b) { 25 | return root; 26 | } 27 | 28 | //search in left and right subtrees 29 | node * leftans = lca(root->left, a, b); 30 | node* rightans = lca(root->right, a, b); 31 | 32 | if (leftans != NULL and rightans != NULL) { 33 | return root; 34 | } 35 | 36 | if (leftans != NULL) { 37 | return leftans; 38 | } 39 | return rightans; 40 | } 41 | 42 | //finding the level of a given node from the root node/any given node 43 | int search(node*root, int key, int level) { 44 | 45 | if (root == NULL) { 46 | return -1; 47 | } 48 | 49 | if (root->key == key) { 50 | return level; 51 | } 52 | 53 | int left = search(root->left, key, level + 1); 54 | if (left != -1) { 55 | return left; 56 | } 57 | return search(root->right, key, level + 1); 58 | } 59 | 60 | //here nodes a and b are the inputs 61 | int shortestDist(node * root,int a,int b){ 62 | //Complete this method 63 | 64 | node* lca_node = lca(root, a, b); //2 65 | 66 | int l1 = search(lca_node, a, 0); 67 | int l2 = search(lca_node, b, 0); 68 | 69 | return l1 + l2; 70 | } -------------------------------------------------------------------------------- /Section 11 - binary search tree/speacialBST.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Node 5 | { 6 | public: 7 | int key; 8 | Node *left; 9 | Node *right; 10 | Node *parent; 11 | }; 12 | 13 | Node* findInOrderSuccessor( Node *inputNode ) 14 | { 15 | // your code goes here 16 | //find the left most child of right subtree if it exists 17 | if(inputNode->right!=NULL){ 18 | Node*temp = inputNode->right; 19 | while(temp->left!=NULL){ 20 | temp = temp->left; 21 | } 22 | return temp; 23 | } 24 | else{ 25 | // traverse the parent till node is a right child of its parent 26 | Node* parent = inputNode->parent; 27 | Node*temp = inputNode; 28 | while(parent!=NULL and parent->right==temp){ 29 | temp = parent; 30 | parent = temp->parent; 31 | } 32 | return parent; 33 | } 34 | } -------------------------------------------------------------------------------- /Section 11 - binary search tree/warmUpBstSearch.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Node 5 | { 6 | public: 7 | int key; 8 | Node *left; 9 | Node *right; 10 | 11 | Node(int key){ 12 | this->key = key; 13 | left = right = NULL; 14 | } 15 | }; 16 | 17 | 18 | bool isPresent(Node * root,int key){ 19 | //Complete this method 20 | if(root==NULL){ 21 | return false; 22 | } 23 | if(root->key==key){ 24 | return true; 25 | } 26 | if(root->key > key){ 27 | return isPresent(root->left,key); 28 | } 29 | return isPresent(root->right,key); 30 | 31 | } -------------------------------------------------------------------------------- /Section 12 - priority queue/mergeKSorterdArrays.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | vector mergeKArrays(vector > arrays){ 6 | //logic 7 | 8 | int k = arrays.size(); 9 | //triplet -> element, array idx, element idx 10 | priority_queue< vector , vector > , greater > > q; 11 | 12 | 13 | vector output; 14 | 15 | //init the heap 16 | for(int i=0;i 2 | using namespace std; 3 | 4 | //Note : Don't Edit the class structure, only update the push method 5 | class MedianHandler{ 6 | public: 7 | float median; 8 | 9 | priority_queue, greater > right; 10 | priority_queue left; //max heap 11 | 12 | void push(int number){ 13 | //Complete this method to update median after every insertion 14 | if(left.empty() and right.empty()){ 15 | median = number; 16 | left.push(number); 17 | } 18 | 19 | else if(left.size()==right.size()){ 20 | if(number <= median){ 21 | left.push(number); 22 | median = left.top(); 23 | } 24 | else{ 25 | right.push(number); 26 | median = right.top(); 27 | } 28 | } 29 | else if(left.size()>right.size()){ 30 | 31 | if(number <= median){ 32 | right.push(left.top()); 33 | left.pop(); 34 | left.push(number); 35 | } 36 | else{ 37 | right.push(number); 38 | } 39 | median = (left.top() + right.top())/2.0; 40 | } 41 | else{ 42 | if(number > median){ 43 | left.push(right.top()); 44 | right.pop(); 45 | right.push(number); 46 | } 47 | else{ 48 | left.push(number); 49 | } 50 | median = (left.top() + right.top())/2.0; 51 | } 52 | 53 | } 54 | float getMedian(){ 55 | //Should return the median in O(1) time 56 | return median; 57 | } 58 | }; -------------------------------------------------------------------------------- /Section 13 - hashing/breakTheChain.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class node{ 5 | public: 6 | int data; 7 | node * next; 8 | 9 | node(int data){ 10 | this->data = data; 11 | } 12 | }; 13 | 14 | 15 | node * breakChain(node * head){ 16 | //Complete this method 17 | unordered_map m; 18 | 19 | node * temp = head; 20 | node * prev = NULL; 21 | while(1){ 22 | m[temp] = true; 23 | 24 | prev = temp; 25 | temp = temp->next; 26 | 27 | if(m[temp]){ 28 | break; 29 | } 30 | } 31 | if(prev!=NULL){ 32 | prev->next = NULL; 33 | } 34 | return head; 35 | } -------------------------------------------------------------------------------- /Section 13 - hashing/groupAnagrams.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | vector> groupAnagrams(vector strs) 5 | { 6 | vector> res; 7 | unordered_map map; 8 | 9 | //sort each string, and make it the key. 10 | for(int i=0; i temp(1, strs[i]); 24 | res.push_back(temp); 25 | 26 | int location = res.size()-1; 27 | map[key] = location; 28 | } 29 | } 30 | return res; 31 | } -------------------------------------------------------------------------------- /Section 13 - hashing/longestKSumSubarray.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | int longestSubarrayKSum(vector arr,int k){ 6 | int n = arr.size(); 7 | unordered_map m; 8 | int pre = 0; 9 | 10 | int len = 0; 11 | 12 | for(int i=0;i 2 | using namespace std; 3 | 4 | 5 | int min_bars_helper(string s,vector words,int idx, unordered_set &m){ 6 | 7 | //base case 8 | if(s[idx]=='\0'){ 9 | return 0; 10 | } 11 | 12 | //rec case 13 | int ans = INT_MAX; 14 | string current_string = ""; 15 | 16 | for(int j=idx; s[j]!='\0';j++){ 17 | current_string += s[j]; 18 | 19 | //at every step you can whether this prefix is present in set 20 | if(m.find(current_string)!=m.end()){ 21 | int remaning_ans = min_bars_helper(s,words,j+1,m); 22 | if(remaning_ans!=-1){ 23 | ans = min(ans, 1 + remaning_ans); 24 | 25 | } 26 | } 27 | } 28 | 29 | if(ans==INT_MAX){ 30 | return -1; 31 | } 32 | return ans; 33 | } 34 | 35 | 36 | 37 | int min_bars(string s, vector words, int n){ 38 | 39 | unordered_set m; 40 | 41 | for(string w:words){ 42 | m.insert(w); 43 | } 44 | 45 | //recursive helper function 46 | int output = min_bars_helper(s,words,0,m); 47 | return output - 1; 48 | } -------------------------------------------------------------------------------- /Section 13 - hashing/warmUp-firstRepeatingLetter.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | char firstRepeatChar(string input){ 6 | 7 | unordered_map m; 8 | 9 | for(char s : input){ 10 | if(m.count(s)==0){ 11 | m[s] = 1; 12 | } 13 | else{ 14 | return s; 15 | } 16 | } 17 | return '\0'; 18 | } -------------------------------------------------------------------------------- /Section 13 - hashing/warmUpCommonElements.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | vector commonElements(vector v1, vector v2) 5 | { 6 | sort(v1.begin(), v1.end()); 7 | sort(v2.begin(), v2.end()); 8 | 9 | vector v; 10 | unordered_map map; 11 | 12 | for(auto x : v1) 13 | map[x] = true; 14 | 15 | for(auto x : v2) 16 | { 17 | if(map[x] == true) 18 | v.push_back(x); 19 | } 20 | 21 | return v; 22 | } 23 | -------------------------------------------------------------------------------- /Section 14 - tries and pattern/minimumXorPair.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | using namespace std; 4 | 5 | 6 | class node{ 7 | public: 8 | node *left; //0 9 | node *right; // 1 10 | }; 11 | 12 | class trie{ 13 | node*root; 14 | 15 | public: 16 | trie(){ 17 | root = new node(); 18 | } 19 | 20 | void insert(int n){ 21 | //bits of that number in the trie 22 | node* temp = root; 23 | for(int i=31;i>=0;i--){ 24 | int bit = (n>>i)&1; 25 | if(bit==0){ 26 | if(temp->left==NULL){ 27 | temp->left = new node(); 28 | } 29 | //go to that node 30 | temp = temp->left; 31 | } 32 | else{ 33 | if(temp->right==NULL){ 34 | temp->right = new node(); 35 | } 36 | temp = temp->right; 37 | } 38 | } 39 | //Insertion is Done 40 | } 41 | 42 | int max_xor_helper(int value){ 43 | 44 | int current_ans = 0; 45 | node* temp = root; 46 | 47 | for(int j=31;j>=0;j--){ 48 | int bit =(value>>j)&1; 49 | 50 | if(bit==0){ 51 | //find the opp value 52 | if(temp->right!=NULL){ 53 | temp = temp->right; 54 | current_ans += (1<left; 58 | } 59 | } 60 | else{ 61 | //look for a zero 62 | if(temp->left!=NULL){ 63 | temp = temp->left; 64 | current_ans += (1<right; 68 | } 69 | } 70 | 71 | } 72 | return current_ans; 73 | 74 | } 75 | int max_xor(vector input,int n){ 76 | 77 | int max_xor = 0; 78 | for(int i=0;i arr){ 91 | trie t; 92 | return t.max_xor(arr,arr.size()); 93 | } 94 | 95 | 96 | -------------------------------------------------------------------------------- /Section 14 - tries and pattern/phoneNumberSearch.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | string keypad[] = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"}; 5 | //words that can be found "IN" the phone number not necessarily EQUAL 6 | //good problem, take unordered set to avoid duplicates 7 | 8 | class Node{ 9 | public: 10 | char ch; 11 | bool isTerminal; 12 | string s; 13 | unordered_map children; 14 | 15 | Node(char ch){ 16 | this->ch = ch; 17 | isTerminal = false; 18 | s = ""; 19 | } 20 | }; 21 | 22 | 23 | class Trie{ 24 | public: 25 | Node *root; 26 | Trie(){ 27 | root = new Node('\0'); 28 | } 29 | void addWord(string word){ 30 | Node* temp = root; 31 | 32 | for(int i=0;ichildren.count(ch)==0){ 35 | temp->children[ch] = new Node(ch); 36 | } 37 | temp = temp->children[ch]; 38 | } 39 | temp->isTerminal = true; 40 | temp->s = word; 41 | } 42 | }; 43 | 44 | //recursive algorithm will get the trie to prune uncessary branches 45 | void validWords(Node *n,string num,int i,unordered_set &outputs){ 46 | //base case 47 | //if we reach a node 48 | if(n->isTerminal){ 49 | outputs.insert(n->s); 50 | } 51 | if(i==num.length()){ 52 | return; 53 | } 54 | 55 | //otherwise 56 | int digit = num[i] - '0'; 57 | 58 | //explore options from current node 59 | 60 | for(int j=0;jchildren.count(ch)!=0){ 64 | validWords(n->children[ch],num,i+1,outputs); 65 | } 66 | } 67 | return; 68 | } 69 | 70 | vector filterNames(string phoneNumber, vector words) { 71 | // Write your code here. 72 | //add all words to the trie 73 | Trie t; 74 | for(auto w : words){ 75 | t.addWord(w); 76 | } 77 | 78 | unordered_set valid_words; 79 | 80 | for(auto i=0;i(valid_words.begin(),valid_words.end()); 85 | } -------------------------------------------------------------------------------- /Section 14 - tries and pattern/prateekBhayia&GooglyStrings.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Node{ 5 | 6 | public: 7 | char ch; 8 | bool isTerminal; 9 | unordered_map children; 10 | 11 | Node(char ch){ 12 | this->ch = ch; 13 | isTerminal = false; 14 | } 15 | }; 16 | 17 | class Trie{ 18 | Node*root; 19 | public: 20 | Trie(){ 21 | root = new Node('\0'); 22 | } 23 | 24 | Node*getRoot(){ 25 | return root; 26 | } 27 | 28 | void addWord(string s){ 29 | 30 | Node*temp = root; 31 | for(char ch : s){ 32 | if(temp->children.count(ch)==0){ 33 | temp->children[ch] = new Node(ch); 34 | } 35 | temp = temp->children[ch]; 36 | } 37 | temp->isTerminal = true; 38 | return; 39 | } 40 | }; 41 | 42 | bool isSpecial(Trie t,Node*root, string s,int i,int cnt){ 43 | //entire string is finished 44 | if(i==s.length()){ 45 | cout<<"Count is "<ch<isTerminal and (cnt + 1) >=2; 47 | } 48 | 49 | char ch = s[i]; 50 | // trie is finished 51 | if(root->children.count(ch)==0){ 52 | return false; 53 | } 54 | //bewkoofon vali mistake <--- 55 | root = root->children[ch]; 56 | //current node is terminal 57 | if(root->isTerminal){ 58 | bool remaining = isSpecial(t,t.getRoot(),s,i+1,cnt+1); 59 | if(remaining==true){ 60 | return true; 61 | } 62 | } 63 | return isSpecial(t,root,s,i+1,cnt); 64 | } 65 | 66 | 67 | vector googlyStrings(vector strings) { 68 | // Write your code here. 69 | Trie t; 70 | 71 | for(auto str:strings){ 72 | t.addWord(str); 73 | } 74 | vector output = {}; 75 | // for every word in the list of strings 76 | //check if it can be formed using atleast 2 words from the trie 77 | 78 | for(auto s : strings){ 79 | //cnt how many words are repeated to form a given string 80 | int cnt = 0; 81 | Node*temp = t.getRoot(); 82 | if(isSpecial(t,temp,s,0,cnt)){ 83 | output.push_back(s); 84 | } 85 | } 86 | 87 | return output; 88 | } -------------------------------------------------------------------------------- /Section 15 - graphs/astranautPairs.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | class Graph{ 7 | list *l; 8 | int V; 9 | public: 10 | Graph(int v){ 11 | V = v; 12 | //Array of Linked List 13 | l = new list[V]; 14 | } 15 | 16 | void addEdge(int i,int j,bool bidir=true){ 17 | l[i].push_back(j); 18 | if(bidir){ 19 | l[j].push_back(i); 20 | } 21 | } 22 | int traverseHelper(int s,bool *visited){ 23 | visited[s] = true; 24 | int size = 1; 25 | 26 | //visit the neighbours of s and thier neighbours recursilvely 27 | for(int nbr:l[s]){ 28 | if(!visited[nbr]){ 29 | size += traverseHelper(nbr,visited); 30 | } 31 | } 32 | return size; 33 | } 34 | //DFS - Depth First Search O(V+E) Linear 35 | int countAstronauts(){ 36 | bool *visited = new bool[V]{0}; 37 | int ans = V*(V-1)/2; 38 | 39 | for(int i=0;i > astronauts){ 54 | //complete this method 55 | Graph g(N); 56 | 57 | for(auto edge : astronauts){ 58 | g.addEdge(edge.first,edge.second); 59 | } 60 | 61 | return g.countAstronauts(); 62 | } 63 | 64 | 65 | -------------------------------------------------------------------------------- /Section 15 - graphs/cycleDetection1UndirectedGraph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | class Graph { 6 | 7 | list *l; 8 | int V; 9 | 10 | public: 11 | Graph(int V) { 12 | l = new list[V]; 13 | } 14 | 15 | void addEdge(int x, int y, bool directed = true) { 16 | l[x].push_back(y); 17 | 18 | if (!directed) { 19 | l[y].push_back(x); 20 | } 21 | } 22 | 23 | bool cycle_helper(int node, bool *visited, int parent) { 24 | 25 | visited[node] = true; 26 | 27 | for (auto nbr : l[node]) { 28 | //two cases 29 | if (!visited[nbr]) { 30 | //go and recursively visit the nbr 31 | bool cycle_mila = cycle_helper(nbr, visited, node); 32 | if (cycle_mila) { 33 | return true; 34 | } 35 | 36 | 37 | } 38 | //nbr is visited but nbr should not be equal to parent 39 | else if (nbr != parent) { 40 | return true; 41 | } 42 | 43 | } 44 | return false; 45 | 46 | } 47 | 48 | bool contains_cycle() { 49 | //Check for Cycle in Directed Graph 50 | bool *visited = new bool[V]; 51 | for (int i = 0; i < V; i++) { 52 | visited[i] = false; 53 | } 54 | return cycle_helper(0, visited, -1); 55 | } 56 | }; 57 | 58 | bool contains_cycle(int V,vector > edges){ 59 | //Complete this method 60 | Graph g(V); 61 | for(auto edge : edges){ 62 | g.addEdge(edge.first,edge.second); 63 | } 64 | return g.contains_cycle(); 65 | } -------------------------------------------------------------------------------- /Section 15 - graphs/cycleDetection2DirectedGraph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | class Graph { 6 | 7 | list *l; 8 | int V; 9 | 10 | public: 11 | Graph(int V) { 12 | this->V = V; 13 | l = new list[V]; 14 | } 15 | 16 | void addEdge(int x, int y, bool directed = true) { 17 | l[x].push_back(y); 18 | 19 | if (!directed) { 20 | l[y].push_back(x); 21 | } 22 | } 23 | 24 | bool cycle_helper(int node, bool *visited, bool *stack) { 25 | 26 | //visit a node 27 | visited[node] = true; 28 | stack[node] = true; 29 | 30 | for (int nbr : l[node]) { 31 | //two cases 32 | if (stack[nbr] == true) { 33 | return true; 34 | } 35 | else if (visited[nbr] == false) { 36 | bool cycle_mila = cycle_helper(nbr, visited, stack); 37 | if (cycle_mila == true) { 38 | return true; 39 | } 40 | } 41 | 42 | } 43 | 44 | //leave a node 45 | stack[node] = false; 46 | return false; 47 | 48 | } 49 | 50 | bool contains_cycle() { 51 | //Check for Cycle in Directed Graph 52 | 53 | bool *visited = new bool[V]; 54 | 55 | bool *stack = new bool[V]; 56 | 57 | for (int i = 0; i < V; i++) { 58 | visited[i] = stack[i] = false; 59 | } 60 | return cycle_helper(0, visited, stack); 61 | } 62 | 63 | }; 64 | 65 | bool contains_cycle(int V,vector > edges){ 66 | //Complete this method 67 | Graph g(V); 68 | for(auto edge : edges){ 69 | g.addEdge(edge.first,edge.second); 70 | } 71 | return g.contains_cycle(); 72 | } -------------------------------------------------------------------------------- /Section 15 - graphs/graphSequence.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | void dfs(vector> matrix,vector > &visited, vector > &cache, int i,int j,int m,int n){ 6 | 7 | visited[i][j] = 1; 8 | 9 | int dx[] = {-1,1,0,0}; 10 | int dy[] = {0,0,1,-1}; 11 | 12 | int cnt = 0; 13 | for(int k=0;k<4;k++){ 14 | int nx = i + dx[k]; 15 | int ny = j + dy[k]; 16 | 17 | if(nx>=0 and ny>=0 and nxmatrix[i][j]){ 18 | int subProblemCnt = 0; 19 | if(visited[nx][ny]){ 20 | cnt = max(cnt,1+cache[nx][ny]); 21 | } 22 | else{ 23 | dfs(matrix,visited,cache,nx,ny,m,n); 24 | cnt = max(cnt,1+cache[nx][ny]); 25 | } 26 | } 27 | } 28 | cache[i][j] = cnt; 29 | return; 30 | } 31 | 32 | int longestPathSequence(vector> matrix) { 33 | // Write your code here. 34 | int m = matrix.size(); 35 | int n = matrix[0].size(); 36 | vector > visited(m+1,vector(n+1,0)); 37 | vector > cache(m+1,vector(n+1,0)); 38 | //do a dfs from every cell //and store the length of of maximum len seq startinf from that cell 39 | int ans = 0; 40 | for(int i=0;i 2 | using namespace std; 3 | 4 | int dfs(vector > matrix,vector > &visited,int i,int j,int m,int n ){ 5 | 6 | //mark the current node as visited 7 | //cout<<"Visiting cell "<=0 and nx=0 and ny> matrix) { 28 | // Write your code here. 29 | int m = matrix.size(); 30 | int n = matrix[0].size(); 31 | 32 | vector > visited(m,vector(n,false)); 33 | 34 | int largest = 0; 35 | 36 | vector result; 37 | for(int i=0;i 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | //dijkshtras 8 | class Node{ 9 | public: 10 | int x,y; 11 | int dist; 12 | 13 | Node(int x,int y,int dist){ 14 | this->x = x; 15 | this->y = y; 16 | this->dist = dist; 17 | } 18 | 19 | }; 20 | 21 | //comparator should return boolean value, indicating whether the element passed as first argument is considered to go before the second in the specific strict weak ordering 22 | class Compare{ 23 | public: 24 | bool operator()(Node a,Node b){ 25 | return a.dist <= b.dist; 26 | } 27 | 28 | }; 29 | 30 | int shortest_path(vector > grid){ 31 | 32 | //----------------///// 33 | int m = grid.size(); 34 | int n = grid[0].size(); 35 | int i = 0; 36 | int j = 0; 37 | 38 | vector > dist(m+1,vector(n+1,INT_MAX)); 39 | 40 | dist[i][j] = grid[0][0]; 41 | set s; 42 | s.insert(Node(i,j,dist[0][0])); 43 | 44 | int dx[] = {0,0,1,-1}; 45 | int dy[] = {1,-1,0,0}; 46 | 47 | while(!s.empty()){ 48 | //get the node that is having smallest dist 49 | auto it = s.begin(); 50 | int cx = it->x; 51 | int cy = it->y; 52 | int cd = it->dist; 53 | s.erase(it); 54 | 55 | //update the neigbours of this node and push them in the set 56 | for(int k=0;k<4;k++){ 57 | int nx = cx + dx[k]; 58 | int ny = cy + dy[k]; 59 | if(nx>=0 and nx=0 and ny cd + grid[nx][ny]){ 60 | //remove the old node from the set 61 | Node temp(nx,ny,dist[nx][ny]); 62 | if(s.find(temp)!=s.end()){ 63 | s.erase(s.find(temp)); 64 | } 65 | //insert the new node in the set 66 | int nd = grid[nx][ny] + cd; 67 | dist[nx][ny] = nd; 68 | s.insert(Node(nx,ny,nd)); 69 | } 70 | } 71 | 72 | } 73 | for(int i=0;i 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | class Graph{ 7 | list *l; 8 | int V; 9 | 10 | public: 11 | Graph(int V){ 12 | this->V = V; 13 | l = new list[V+1]; 14 | } 15 | void addEdge(int u,int v){ 16 | l[u].push_back(v); 17 | } 18 | 19 | int minCostBFS(int src,int dest){ 20 | queue q; 21 | vector visited(V,false); 22 | vector dist(V,0); 23 | 24 | q.push(src); 25 | visited[src] = true; 26 | dist[src] = 0; 27 | 28 | while(!q.empty()){ 29 | int f = q.front(); 30 | q.pop(); 31 | 32 | for(int nbr : l[f]){ 33 | if(!visited[nbr]){ 34 | q.push(nbr); 35 | visited[nbr] = true; 36 | dist[nbr] = dist[f] + 1; 37 | } 38 | } 39 | } 40 | return dist[dest]; 41 | } 42 | 43 | }; 44 | 45 | 46 | 47 | int min_dice_throws(int n,vector > snakes, vector > ladders){ 48 | vector board(n+1,0); 49 | 50 | //board to graph conversion 51 | for(auto sp: snakes){ 52 | int s = sp.first; 53 | int e = sp.second; 54 | board[s] = e - s; 55 | } 56 | 57 | for(auto lp: ladders){ 58 | int s = lp.first; 59 | int e = lp.second; 60 | board[s] = e - s; 61 | } 62 | 63 | //Graph 64 | Graph g(n+1); 65 | for(int u=1;u 2 | using namespace std; 3 | 4 | long long minimumCost(vector stones, int k) 5 | { 6 | int n = stones.size(); 7 | 8 | vector dp(n, 0); 9 | for(int i=1; i 2 | using namespace std; 3 | 4 | long long coinChange(int s, int n , vector a, long long dp[500][100]) 5 | { 6 | if (n < 0 || s < 0) return 0; 7 | if (s == 0) return 1; 8 | 9 | if (dp[s][n] != 0) return dp[s][n]; 10 | 11 | long long op1 = coinChange(s, n - 1, a, dp); 12 | long long op2 = coinChange(s - a[n], n, a, dp); 13 | 14 | return dp[s][n] = op1 + op2; 15 | } 16 | 17 | long long findCombinations(int n, vector coins) 18 | { 19 | long long dp[500][100] = {{0}}; 20 | return coinChange(n, coins.size()-1, coins, dp); 21 | } -------------------------------------------------------------------------------- /Section 17 - dp 2D/editDistance.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int minDistance(string str1, int n1, string str2, int n2, int dp[500][500]) 5 | { 6 | if (n1 == 0) return n2; 7 | if (n2 == 0) return n1; 8 | 9 | if (dp[n1][n2] != -1) return dp[n1][n2]; 10 | 11 | if (str1[n1 - 1] == str2[n2 - 1]) 12 | return dp[n1][n2] = minDistance(str1, n1 - 1, str2, n2 - 1, dp); 13 | else 14 | { 15 | int op1, op2, op3; 16 | op1 = minDistance(str1, n1, str2, n2 - 1, dp); // insert 17 | op2 = minDistance(str1, n1 - 1, str2, n2, dp); // remove 18 | op3 = minDistance(str1, n1 - 1, str2, n2 - 1, dp); // replace 19 | 20 | return dp[n1][n2] = 1 + min(op1, min(op2, op3)); 21 | } 22 | } 23 | 24 | int editDistance(string str1, string str2) 25 | { 26 | int dp[500][500]; 27 | memset(dp, -1, sizeof dp); 28 | 29 | int n1 = str1.size(); 30 | int n2 = str2.size(); 31 | 32 | int ans = minDistance(str1, n1, str2, n2, dp); 33 | return ans; 34 | } -------------------------------------------------------------------------------- /Section 17 - dp 2D/gameOfWits.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int dp[105][105]; 4 | int game(string s, int i, int j, int dp[105][105]){ 5 | if(i+1==j){ 6 | if(s[i]=='O' && s[j]=='O'){ 7 | return 2; 8 | } 9 | else if(s[i]=='H'&& s[j]=='H'){ 10 | return -3; 11 | } 12 | else{ 13 | return -1; 14 | } 15 | } 16 | if(i==j){ 17 | if(s[i]=='O'){ 18 | return 1; 19 | } 20 | else{ 21 | return -2; 22 | } 23 | } 24 | if(dp[i][j] != 0) return dp[i][j]; 25 | 26 | 27 | if(s[i]=='H' && s[j]=='H'){ 28 | return dp[i][j] = -1* (j-i+1) - 1; 29 | } 30 | else if(s[i]=='H' && s[j]=='O'){ 31 | int op1=INT_MAX; 32 | if(s[j-1]=='H'){ 33 | op1 = game(s,i,j-2,dp); 34 | } 35 | int op2 = game(s,i+1,j-1,dp); 36 | return dp[i][j] = min(op1,op2); 37 | } 38 | else if(s[i]=='O' && s[j]=='H'){ 39 | int op1=INT_MAX; 40 | if(s[i+1]=='H'){ 41 | op1 = game(s,i+2,j,dp); 42 | } 43 | int op2 = game(s,i+1,j-1,dp); 44 | return dp[i][j] = min(op1,op2); 45 | } 46 | else{ 47 | 48 | if(s[i+1]=='O'){ 49 | return j-i+1; 50 | } 51 | else if(s[j-1]=='O'){ 52 | 53 | return j-i+1; 54 | } 55 | else { 56 | int op1=game(s,i+2,j,dp); 57 | int op2=game(s,i,j-2,dp); 58 | return dp[i][j] = max(op1,op2); 59 | } 60 | } 61 | } 62 | pair GameOfWits(string s){ 63 | int n=s.length(); 64 | int ans= game(s,0,n-1,dp); 65 | if(ans>0){ 66 | return {'O',abs(ans)}; 67 | } 68 | else 69 | return {'H',abs(ans)}; 70 | 71 | } -------------------------------------------------------------------------------- /Section 17 - dp 2D/mixturesSpoj.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | long long mixtures(vector v, int i, int j, long long dp[500][500]) 5 | { 6 | if (i == j) return 0; 7 | if (dp[i][j] != -1) return dp[i][j]; 8 | 9 | long long res = INT_MAX; 10 | 11 | for (int k = i; k < j; k++) 12 | { 13 | long long ans = mixtures(v, i, k, dp) + mixtures(v, k + 1, j, dp); 14 | ans += ( ( (v[k] - (i > 0 ? v[i - 1] : 0) ) % 100 ) * ((v[j] - v[k]) % 100) ); 15 | res = min(res, ans); 16 | } 17 | 18 | return dp[i][j] = res; 19 | } 20 | 21 | long long minimumSmoke(vector v) 22 | { 23 | long long dp[500][500]; 24 | memset(dp, -1, sizeof dp); 25 | 26 | int n = v.size(); 27 | for (int i = 1; i < n; i++) 28 | { 29 | v[i] += v[i - 1]; //cumulative sum 30 | } 31 | 32 | long long ans = mixtures(v, 0, n - 1, dp); 33 | return ans; 34 | } 35 | -------------------------------------------------------------------------------- /Section 17 - dp 2D/palindromicPartitioning.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int palindromePartitioningMinCuts(string s) { 7 | 8 | // 2d grid 9 | int n = s.length(); 10 | vector > isPalin(n+1,vector(n,false)); 11 | 12 | for(int i=0;i cuts(n+1,INT_MAX); 33 | 34 | for(int i=0;i 2 | using namespace std; 3 | 4 | int match(string s, int n, string p, int m, int dp[500][500]) 5 | { 6 | if (n == 0 && m == 0) 7 | return 1; 8 | if (m == 0) 9 | return 0; 10 | 11 | if (n == 0) 12 | { 13 | while (m > 0) 14 | { 15 | if (p[m - 1] != '*') 16 | return 0; 17 | m--; 18 | } 19 | return 1; 20 | } 21 | 22 | if (dp[n][m] != -1) 23 | return dp[n][m]; 24 | 25 | if (p[m - 1] == '*') 26 | return dp[n][m] = match(s, n - 1, p, m, dp) || match(s, n, p, m - 1, dp); 27 | 28 | else if (p[m - 1] == '?') 29 | return dp[n][m] = match(s, n - 1, p, m - 1, dp); 30 | 31 | else if (s[n - 1] == p[m - 1]) 32 | return dp[n][m] = match(s, n - 1, p, m - 1, dp); 33 | 34 | else 35 | return dp[n][m] = 0; 36 | 37 | } 38 | 39 | bool patternMatching(string s, string p) 40 | { 41 | int dp[500][500]; 42 | memset(dp, -1, sizeof dp); 43 | 44 | int n = s.size(); 45 | int m = p.size(); 46 | 47 | int ans = match(s, n, p, m, dp); 48 | 49 | if (ans == 1) 50 | return true; 51 | else 52 | return false; 53 | } 54 | --------------------------------------------------------------------------------