diff --git a/Arrays/Find Permutation.cpp b/Arrays/Find Permutation.cpp new file mode 100644 index 0000000..83c9ff2 --- /dev/null +++ b/Arrays/Find Permutation.cpp @@ -0,0 +1,32 @@ +/* +Solution by : Bhavik Dhandhalya +Given a positive integer n and a string s consisting only of letters D or I, you have to find any permutation of first n positive integer that satisfy the given input string. + +D means the next number is smaller, while I means the next number is greater. + +Notes +Length of given string s will always equal to n - 1 +Your solution should run in linear time and space. + +Input 1: + +n = 3 +s = ID +Return: [1, 3, 2] + +Solution Complexity : O(N) time and O(1) space +Refer this URL for lexicographically smaller permutation solution: +https://leetcode.com/articles/find-permutation/ +*/ + +vector Solution::findPerm(const string A, int B) { + vector < int > ans; + int n = A.length(); + int maxi = n + 1, mini = 1; + for (int i = 0; i < n; i++) { + if (A[i] == 'I') ans.push_back(mini++); + if (A[i] == 'D') ans.push_back(maxi--); + } + ans.push_back(maxi); + return ans; +} diff --git a/Arrays/Flip simple code.cpp b/Arrays/Flip simple code.cpp new file mode 100644 index 0000000..5c5e87c --- /dev/null +++ b/Arrays/Flip simple code.cpp @@ -0,0 +1,51 @@ +/* +You are given a binary string(i.e. with characters 0 and 1) S consisting of characters S1, S2, …, SN. In a single operation, you can choose two indices L and R such that 1 ≤ L ≤ R ≤ N and flip the characters SL, SL+1, …, SR. By flipping, we mean change character 0 to 1 and vice-versa. + +Your aim is to perform ATMOST one operation such that in final string number of 1s is maximised. If you don’t want to perform the operation, return an empty array. Else, return an array consisting of two elements denoting L and R. If there are multiple solutions, return the lexicographically smallest pair of L and R. + +Notes: + +Pair (a, b) is lexicographically smaller than pair (c, d) if a < c or, if a == c and b < d. +For example, +S = 010 +Output = [1 1] +*/ + +vector Solution::flip(string A) { + int n = A.length(); + int ones = 0; + int zeros = 0; + int L = INT_MAX, R = 0; + int ansL = 0, ansR = 0; + int prev = 0; + bool found = false; + + for (int i = 0; i < n; i++) { + ones += A[i] == '1'; + zeros += A[i] == '0'; + if (zeros) found = true; + + if (ones > zeros) { + ones = 0; + zeros = 0; + L = INT_MAX; + R = 0; + } else if (A[i] == '0') { + L = min(L, i); + R = i; + + if (zeros - ones > prev) { + ansR = R; + ansL = L; + prev = zeros - ones; + } + } + } + + vector < int > ans; + if (found) { + ans.push_back(ansL + 1); + ans.push_back(ansR + 1); + } + return ans; +} diff --git a/Arrays/MaxDistance.cpp b/Arrays/MaxDistance.cpp index d330e72..bc867f0 100644 --- a/Arrays/MaxDistance.cpp +++ b/Arrays/MaxDistance.cpp @@ -1,41 +1,80 @@ // https://www.interviewbit.com/problems/max-distance/ + +int Solution::maximumGap(const vector &A) { + // Base case + if(A.size() <= 1)return 0; + + // Make two arrays such that one of them holds the minimum from the left + // and the other holds maximum from the right + vector v1 (A.size(), 0), v2(A.size(), 0); + + // Fill the first array with minimum from the left + v1[0] = A[0]; + for(int i = 1 ; i < A.size(); i++)v1[i] = min(v1[i-1], A[i]); + + // Fill the second array with maximum from the right + v2[A.size()-1] = A[A.size()-1]; + for(int i = A.size()-2 ; i >= 0 ; i--)v2[i] = max(v2[i+1], A[i]); + + + int i = 0, j = 0; + int ans = -1; + // While we don't traverse the complete array, check if the minimum element is indeed + // less than the maximum element in the other array, if yes, update the answer. + // Move the pointer as required. If the element in second array is greater than + // that in first array, keep moving the second pointer and update the answer + // else move the first pointer. + while(j < A.size() && i < A.size()){ + if(v2[j] >= v1[i]){ + if(j-i > ans){ + ans = j-i; + } + j = j + 1; + }else i = i + 1; + } + return ans; +} + + + + // Here we are making an array to check whether all the elements on the left of an index are smaller than it or not // If true then we are checking for greater j such that A[j] is greater than A[i]. If so then that j is greater than all i on the left // also. On finding such a j or a false in the check array, we decrement i. -int Solution::maximumGap(const vector &A) { - // Do not write main() function. - // Do not read input, instead use the arguments to the function. - // Do not print the output, instead return values as specified - // Still have a doubt. Checkout www.interviewbit.com/pages/sample_codes/ for more details - vector tempArr(A.size()); - int min = A[0]; - int max_distance = 0; - int i = A.size()-1; - int j = A.size()-1; +// int Solution::maximumGap(const vector &A) { +// // Do not write main() function. +// // Do not read input, instead use the arguments to the function. +// // Do not print the output, instead return values as specified +// // Still have a doubt. Checkout www.interviewbit.com/pages/sample_codes/ for more details +// vector tempArr(A.size()); +// int min = A[0]; +// int max_distance = 0; +// int i = A.size()-1; +// int j = A.size()-1; - for(int i = 0; i < A.size(); i++){ - if(A[i] > min){ - tempArr[i] = false; - } - else{ - min = A[i]; - tempArr[i] = true; - } - } +// for(int i = 0; i < A.size(); i++){ +// if(A[i] > min){ +// tempArr[i] = false; +// } +// else{ +// min = A[i]; +// tempArr[i] = true; +// } +// } - LOOP:while(i >= 0){ - if(tempArr[i] == false){ - i--; - goto LOOP; - } - while((A[i] > A[j]) && (j > i)){ - j--; - } - if((j-i) > max_distance){ - max_distance = j-i; - } - i--; - } - return max_distance; -} +// LOOP:while(i >= 0){ +// if(tempArr[i] == false){ +// i--; +// goto LOOP; +// } +// while((A[i] > A[j]) && (j > i)){ +// j--; +// } +// if((j-i) > max_distance){ +// max_distance = j-i; +// } +// i--; +// } +// return max_distance; +// } diff --git a/Arrays/MinStepsInInfiniteGrid.cpp b/Arrays/MinStepsInInfiniteGrid.cpp index e4932a0..0d227f0 100644 --- a/Arrays/MinStepsInInfiniteGrid.cpp +++ b/Arrays/MinStepsInInfiniteGrid.cpp @@ -1,6 +1,9 @@ // https://www.interviewbit.com/problems/min-steps-in-infinite-grid/ // Input : X and Y co-ordinates of the points in order. // Each point is represented by (X[i], Y[i]) + +// Explanatory code +/* int Solution::coverPoints(vector &X, vector &Y) { int steps = 0, dx, dy, i = 0; @@ -38,3 +41,19 @@ int Solution::coverPoints(vector &X, vector &Y) { return steps; } +*/ + +// Concise code +int coverPoints(vector &X, vector &Y) { + + int size1=X.size(),size2=Y.size(),ans=0; + + for(int i=1;i &A, vector &temp, set> &ans) { + if(i == A.size() || sum >= k){ + if(sum == k){ + ans.insert(temp); + } + return; + } + + temp.push_back(A[i]); + aux(i, sum+A[i], k, A, temp, ans); + aux(i+1, sum+A[i], k, A, temp, ans); + temp.pop_back(); + aux(i+1, sum, k, A, temp, ans); +} + +vector > Solution::combinationSum(vector &A, int B) { + set> ans; + sort(A.begin(), A.end()); + vector temp; + aux(0, 0, B, A, temp, ans); + vector> res; + + for(auto i = ans.begin(); i != ans.end(); i++){ + res.push_back(*i); + } + return res; +} diff --git a/Backtracking/NQueens.cpp b/Backtracking/NQueens.cpp new file mode 100644 index 0000000..8164dad --- /dev/null +++ b/Backtracking/NQueens.cpp @@ -0,0 +1,50 @@ +vector >ans; +int n; + +void recur(int ind, vector pos) +{ + int i,j; + if(ind == n) + { + vector valid; + for(i=0;i > Solution::solveNQueens(int A) +{ + ans.clear(); + vector pos; + int i; + n = A; + recur(0,pos); + return ans; +} diff --git a/Binary-Search/RotatedSortedArraySearch.cpp b/Binary-Search/RotatedSortedArraySearch.cpp index 6f46735..6d6ce5d 100644 --- a/Binary-Search/RotatedSortedArraySearch.cpp +++ b/Binary-Search/RotatedSortedArraySearch.cpp @@ -1,5 +1,43 @@ // https://www.interviewbit.com/problems/rotated-sorted-array-search/ +int search1(const vector &arr, int low, int high, int B) +{ + if (low > high) return -1; + + int mid = (low) + (high-low)/2; + if (arr[mid] == B) return mid; + + if (arr[low] <= arr[mid]) + { + if (B >= arr[low] && B <= arr[mid]) + return search1(arr, low, mid-1, B); + + return search1(arr, mid+1, high, B); + } + + else if (arr[mid] <= arr[high]) + { + if (B >= arr[mid] && B <= arr[high]) + return search1(arr, mid+1, high, B); + + return search1(arr, low, mid-1, B); + } +} + + +int Solution::search(const vector &A, int B) { + + int n = A.size(); + int i = search1(A, 0, n-1, B); + + if (i != -1) + return i; + else + return -1; + +} + +/* int findPivot(const vector &A){ int start = 0; int end = A.size()-1; @@ -64,3 +102,4 @@ int Solution::search(const vector &A, int B) { // B < A[pivot] } +*/ diff --git a/Bit-Manipulation/DivideInteger.cpp b/Bit-Manipulation/DivideInteger.cpp new file mode 100644 index 0000000..cc842e0 --- /dev/null +++ b/Bit-Manipulation/DivideInteger.cpp @@ -0,0 +1,18 @@ +int Solution::divide(int a, int b) { + if(a==0) + return 0; + if(b==0) + return (INT_MAX); + int sign=1; + //remove sign of operands + int t=0,q=0; + a=abs(a); + b=abs(b); + for(int i=31;i>=0;--i){ + if(t+(b<=INT_MAX||sign*q > &A) { + int ans,i,j,dn,rig,r,c,sum; + int n=A.size(); + int m=A[0].size(); + vector > rsum=A; + for(r=0;r=0;c--) + { + rsum[r][c]=A[r][c]+rsum[r][c+1]; + } + } + int ma=A[n-1][m-1]; + int dp[n][m]; + memset(dp,0,sizeof(dp)); + for(j=m-1;j>=0;j--) + { + for(i=n-1;i>=0;i--) + { + rig=0; + dn=0; + if(i!=n-1) + { + dn=dp[i+1][j]; + } + if(j!=m-1) + { + rig=rsum[i][j+1]; + } + dp[i][j]=A[i][j]+rig+dn; + ma=max(ma,dp[i][j]); + } + } + return(ma); +} diff --git a/DynamicProgramming/LargestAreaOfRectangleWithPermutations.cpp b/DynamicProgramming/LargestAreaOfRectangleWithPermutations.cpp new file mode 100644 index 0000000..2144aca --- /dev/null +++ b/DynamicProgramming/LargestAreaOfRectangleWithPermutations.cpp @@ -0,0 +1,47 @@ +int Solution::solve(vector > &A) { + + int hist[A.size()+1][A[0].size()+1]; + + for (int i=0; i=0; j--) + { + if (count[j] > 0) + { + for (int k=0; k max_area) + max_area = curr_area; + } + } + return max_area; +} diff --git a/DynamicProgramming/Scramble String.cpp b/DynamicProgramming/Scramble String.cpp new file mode 100644 index 0000000..157a4c9 --- /dev/null +++ b/DynamicProgramming/Scramble String.cpp @@ -0,0 +1,41 @@ +int Solution::isScramble(string A, string B) +{ + + int length1 = A.length(); + //int length2 = B.length(); + + if(length1 != B.length()) + return false; + if(A == B) + return true; + + bool scrambled[length1][length1][length1]; + for (int i=0; i < length1; ++i) + { + for (int j=0; j < length1; ++j) + { + scrambled[i][j][0] = (A[i] == B[j]); + } + } + + for (int k=1; k < length1; ++k) + { + for (int i=0; i < length1 - k; ++i) + { + for (int j=0; j < length1 - k; ++j) + { + scrambled[i][j][k] = false; + for (int p=0; p < k; ++p) + { + if ((scrambled[i][j][p] && scrambled[i+p+1][j+p+1][k-p-1]) + || (scrambled[i][j+k-p][p] && scrambled[i+p+1][j][k-p-1])) { + scrambled[i][j][k] = true; + break; + } + } + } + } + } + + return scrambled[0][0][length1-1]; + } diff --git a/DynamicProgramming/Tushar'sBirthdayBombs.cpp b/DynamicProgramming/Tushar'sBirthdayBombs.cpp new file mode 100644 index 0000000..2d1da5f --- /dev/null +++ b/DynamicProgramming/Tushar'sBirthdayBombs.cpp @@ -0,0 +1,43 @@ +vector Solution::solve(int A, vector &B) +{ + int mn = INT_MAX; + int n = B.size(),i,j,pos; + for(i=0;i order; + for(i=0;i= 0) + { + ind = j; + rem = rem-B[j]+B[pos]; + break; + } + } + if(j == n) + break; + order[i] = j; + i++; + // pos = order.size(); + } + return order; +} diff --git a/Graphs/CloneGraph.cpp b/Graphs/CloneGraph.cpp new file mode 100644 index 0000000..ed6e982 --- /dev/null +++ b/Graphs/CloneGraph.cpp @@ -0,0 +1,46 @@ +/** + * Definition for undirected graph. + * struct UndirectedGraphNode { + * int label; + * vector neighbors; + * UndirectedGraphNode(int x) : label(x) {}; + * }; + */ +UndirectedGraphNode *Solution::cloneGraph(UndirectedGraphNode *node) { + std::map m; + queue q; + + q.push(node); + + while (!q.empty()) { + auto n = q.front(); + q.pop(); + + UndirectedGraphNode* new_node = nullptr; + + if (m.find(n->label) == m.end()) { + // not exist in map + new_node = new UndirectedGraphNode(n->label); + m[n->label] = new_node; + } else { + // exist in map + new_node = m[n->label]; + } + + for (auto neighbor: n->neighbors) { + if (m.find(neighbor->label) == m.end()) { + // not exist in map + m[neighbor->label] = new UndirectedGraphNode(neighbor->label); + new_node->neighbors.push_back(m[neighbor->label]); + + q.push(neighbor); + } else { + // exist in map + new_node->neighbors.push_back(m[neighbor->label]); + } + } + } + + return m[node->label]; +} + diff --git a/Graphs/LargestDistanceBetweenNodesOfATree.cpp b/Graphs/LargestDistanceBetweenNodesOfATree.cpp new file mode 100644 index 0000000..9dd1ecd --- /dev/null +++ b/Graphs/LargestDistanceBetweenNodesOfATree.cpp @@ -0,0 +1,58 @@ +pair process(queue >& q, vector& visited, unordered_map >& x){ + // Typical BFS with keeping track of the longest distance and farthest element. + int maxi = INT_MIN, farthest = 0; + while(!q.empty()){ + int node = q.front().first; + int distance = q.front().second; + q.pop(); + if(distance > maxi){ + maxi = distance; + farthest = node; + } + visited[node] = 1; + for(int i = 0; i < x[node].size(); i++){ + if(!visited[x[node][i]]){ + visited[x[node][i]] = 1; + q.push({x[node][i], distance+1}); + } + } + } + return {maxi, farthest}; +} + +int Solution::solve(vector &A) { + // Base Case + if(A.size() <= 1)return 0; + + // Visited array to keep track of visited elements + vector visited(A.size(), 0); + + // Map to make the graph from given array + unordered_map > x; + x.clear(); + + for(int i = 0; i < A.size(); i++){ + // If the value is -1, it doesn't have any parent. + // Make the pairs in the adj. list type map + if( A[i] != -1){ + x[A[i]].push_back(i); + x[i].push_back(A[i]); + } + } + + // Start from the first element in the array and mark it visited. + queue > q; + q.push({0, 0}); + visited[0] = 1; + + // Gets the farthest element from the first element + int farthest = process(q, visited, x).second; + + vector vis(A.size(), 0); + + // Now apply BFS on the farthest element found and return the distance + // of the farthest element found so far. + q.push({farthest, 0}); + vis[farthest] = 1; + return process(q, vis, x).first; +} diff --git a/Graphs/SmallestSequenceWithGivenPrimes.cpp b/Graphs/SmallestSequenceWithGivenPrimes.cpp new file mode 100644 index 0000000..befd7a6 --- /dev/null +++ b/Graphs/SmallestSequenceWithGivenPrimes.cpp @@ -0,0 +1,22 @@ +vector Solution::solve(int A, int B, int C, int D) +{ + set s; + swap(A,D); + int ctr = 0; + vector ans; + s.insert(B); + s.insert(C); + s.insert(D); + while(ctr fib; + fib.push_back(1);fib.push_back(1); // now u have 1 and 1 at v[0] and v[1] + for(int i=2;fib[i-1]0){ + while(fib[size]>n){ // find the largest fibonaci number < n + size--; + } // now decraese the largest fibonaci number from n + n=n-fib[size]; + ans++; + } + return ans; +} + + + +// int Solution::fibsum(int A) { +// // Do not write main() function. +// // Do not read input, instead use the arguments to the function. +// // Do not print the output, instead return values as specified +// // Still have a doubt. Checkout www.interviewbit.com/pages/sample_codes/ for more details - vector vec; +// vector vec; - vec.push_back(1); - vec.push_back(1); +// vec.push_back(1); +// vec.push_back(1); - int fib, i = 2; +// int fib, i = 2; - while(fib <= A){ - fib = vec[i-2] + vec[i-1]; - vec.push_back(fib); - i++; - } +// while(fib <= A){ +// fib = vec[i-2] + vec[i-1]; +// vec.push_back(fib); +// i++; +// } - int j = vec.size()-1; - int sol = 0; +// int j = vec.size()-1; +// int sol = 0; - LOOP:while(A && j >= 0){ - if(vec[j] == A){ - sol++; - return sol; - } - else if(vec[j] < A){ - sol++; - A = A - vec[j]; - goto LOOP; - } - j--; - } +// LOOP:while(A && j >= 0){ +// if(vec[j] == A){ +// sol++; +// return sol; +// } +// else if(vec[j] < A){ +// sol++; +// A = A - vec[j]; +// goto LOOP; +// } +// j--; +// } - return 0; -} +// return 0; +// } diff --git a/Graphs/WordSearchBoard.cpp b/Graphs/WordSearchBoard.cpp new file mode 100644 index 0000000..88df2b3 --- /dev/null +++ b/Graphs/WordSearchBoard.cpp @@ -0,0 +1,49 @@ +vector x({0, 1, -1, 0}); +vector y({1, 0, 0, -1}); + +// Check if the coordinates are safe to visit +bool isSafe(int a, int b, int c, int d){ + if(a >= 0 && a < c && b >= 0 && b < d)return true; + return false; +} + + +void explore(bool& pivot, int val, int a, int b, vector& A, string B){ + // If reached on the last index of the string, + // it means we have found the reqd. string and + // so we return + if(val == B.size()-1){ + pivot = true; + return; + } + + for(int i = 0; i < x.size(); i++){ + int first = a + x[i]; + int second = b + y[i]; + + // Explore the adjacent node only if its value is the next index in the + // given string + if(isSafe(first, second, A.size(), A[0].size()) && A[first][second] == B[val+1]){ + explore(pivot, val+1, first, second, A, B); + // To reduce time limit. + if(pivot == true)return; + } + } + +} + +int Solution::exist(vector &A, string B) { + int l = A.size(), m = A[0].size(); + if(l == 0)return 0; + + bool pivot = false; + for(int i = 0; i < l; i++){ + for(int k = 0; k < m; k++){ + if(A[i][k] == B[0]){ + explore(pivot, 0, i, k, A, B); + } + if(pivot)return pivot; + } + } + return pivot; +} diff --git a/Graphs/knightOnAChess.cpp b/Graphs/knightOnAChess.cpp new file mode 100644 index 0000000..b97ce52 --- /dev/null +++ b/Graphs/knightOnAChess.cpp @@ -0,0 +1,40 @@ +vector x ({1, 2, 2, 1, -1, -2, -1, -2}); +vector y ({2, 1, -1, -2, 2, 1, -2, -1}); + +bool isSafe(int i , int j ,int N, int M){ + if(i >= 0 && i < N && j >= 0 && j < M)return true; + + return false; +} + +int explore(queue > >& q, int A, int B, int C, int D, int E, int F, vector >& visited, int &count){ + while(!q.empty()){ + int distance = q.front().first; + int c = q.front().second.first; + int d = q.front().second.second; + q.pop(); + if ( c == E && d == F)return distance; + visited[c][d] = 1; + + for(int i = 0; i < x.size(); i++){ + int first = c + x[i]; + int second = d + y[i]; + if(isSafe(first, second, A, B)){ + if(visited[first][second] == 0){ + visited[first][second] = 1; + q.push({distance+1, {first, second}}); + } + } + } + } + return -1; +} + +int Solution::knight(int A, int B, int C, int D, int E, int F) { + vector > visited (A, vector (B, 0)); + + int count = 0; + queue > > q; + q.push({0, {C-1, D-1}}); + return explore(q, A, B, C-1, D-1, E-1, F-1, visited, count); +} diff --git a/Hashing/Anagrams.cpp b/Hashing/Anagrams.cpp index cde7fc5..411090b 100644 --- a/Hashing/Anagrams.cpp +++ b/Hashing/Anagrams.cpp @@ -1,30 +1,12 @@ // https://www.interviewbit.com/problems/anagrams/ -string mySort(string temp){ - vector str; - for(int i = 0; i < temp.size(); i++){ - str.push_back((int)temp[i]); - } - sort(str.begin(), str.end()); - string ans = ""; - for(int i = 0; i < str.size(); i++){ - ans = ans + (char)str[i]; - } - - return ans; -} - vector > Solution::anagrams(const vector &A) { - // Do not write main() function. - // Do not read input, instead use the arguments to the function. - // Do not print the output, instead return values as specified - // Still have a doubt. Checkout www.interviewbit.com/pages/sample_codes/ for more details - vector > sol; unordered_map > myMap; - + string temp; for(int i = 0; i < A.size(); i++){ - string temp = mySort(A[i]); + temp = A[i]; + sort(temp.begin(),temp.end()); myMap[temp].push_back(i+1); } diff --git a/Heaps-and-Maps/WaysToFormMaxHeap.cpp b/Heaps-and-Maps/WaysToFormMaxHeap.cpp new file mode 100644 index 0000000..acf5370 --- /dev/null +++ b/Heaps-and-Maps/WaysToFormMaxHeap.cpp @@ -0,0 +1,47 @@ +long long dp[105]; +long long comb[105][105]; +#define MOD 1000000007 +int rec(int n) +{ + if(n<=1) + return 1; + if(dp[n] != -1) + return dp[n]; + int i; + int fill = 0; + int pw = 2; + int left,right; + left = right = 0; + + while(fill+pw < n-1) + { + fill += pw; + left += pw/2; + right += pw/2; + pw *= 2; + } + int rem = n-1-fill; + if(rem > pw/2) + { + left += pw/2; + right += (rem-pw/2); + } + else + left += rem; + + return dp[n] = (((rec(left)*1LL*rec(right))%MOD)*1LL*comb[n-1][left])%MOD; +} +int Solution::solve(int A) +{ + int i,j; + for(i=0;i<=100;i++) + dp[i] = -1; + comb[0][0] = 1; + for(i=1;i<=100;i++) + { + comb[i][0] = comb[i][i] = 1; + for(j=1;jnext)return A; + +// ListNode* head = A->next; +// ListNode* p = reverseList(A->next); +// A->next->next = A; +// A->next = NULL; +// return p; +// } diff --git a/Math/CityTour.cpp b/Math/CityTour.cpp new file mode 100644 index 0000000..790b517 --- /dev/null +++ b/Math/CityTour.cpp @@ -0,0 +1,164 @@ +static const int MODULUS = 1000000007; + +// compute 2^k modulo MODULUS +int power2modulo(int k) +{ + long result = 1; + for (int i=0; i numerator, denominator; + priority_queue new_numerator, new_denominator; + int a = std::max(r, n - r); + int b = n - a; + long result = 1; + long T; + + // do not compute factorials, but push the terms that make up the factorials + for (int i=a+1; i<=n; i++) { + numerator.push(i); + } + for (int i=2; i<=b; i++) { + denominator.push(i); + } + + // we try to cancel out the GCD of each numerator with each denominator + int n_len = numerator.size(); + for (int i=0; i segment_t; +typedef vector segments_t; + +// Compute the number of permutations of paths, +// Combine the two segments at a time for ease of understanding. +// For example, consider two segments with 3 cities (AAA) and 4 cities (BBBB). +// There are 7 choose 3 ways to interleave the cities from the two segments. +// One such interleaving pattern is: ABAABBB. +// If there are X different paths for the A cities and Y different paths for B, +// the new combined segment has 7 cities and 7 choose 3 times X times Y paths. +int arrangements(segments_t &segments) { + long num_paths; + while (true) { + auto itA = segments.begin(); + auto itB = segments.end()-1; + if (itA == itB) { + num_paths = itA->second; + break; + } else { + itA->first += itB->first; + num_paths = binomial(itA->first, itB->first); + num_paths %= MODULUS; + num_paths = (num_paths * itA->second) % MODULUS; + num_paths = (num_paths * itB->second) % MODULUS; + itA->second = num_paths; + segments.erase(itB); + } + } + return num_paths; +} + +int Solution::solve(int A, vector &B) { + priority_queue V; + segments_t segments; + + if (B.size() == 0) + return 0; + + // Insert B into priority queue V so we can sort the cities. + for (auto p : B) { + V.push(p); + } + + int right = V.top(); + V.pop(); + if (right < A) { + // Account for corner case where last region is one-sided. + // In this case, there is only one path. + segments.push_back(pair(A - right, 1)); + } + while (!V.empty()) { + if ((V.top() + 1) == right) { + // We skip over adjacent cities that have been visited. + V.pop(); + --right; + } else { + // We make a maximal segment of consecutive unvisited cities. + int consecutive = right; + right = V.top(); + V.pop(); + consecutive -= right + 1; + // For a segment of N consecutive unvisited cities bordered on both sides + // by visited cities, there are 2^^(N-1) posible paths. + // Record the length and number of paths. + segments.push_back(segment_t(consecutive, power2modulo(consecutive-1))); + } + } + if (right != 1) { + // Account for corner case where last region is one-sided. + segments.push_back(segment_t(right - 1, 1)); + } + + return arrangements(segments); +} \ No newline at end of file diff --git a/Math/FizzBuzz.cpp b/Math/FizzBuzz.cpp new file mode 100644 index 0000000..97c9a58 --- /dev/null +++ b/Math/FizzBuzz.cpp @@ -0,0 +1,17 @@ +//see this to check other variations of fizzbuzz: https://www.geeksforgeeks.org/fizz-buzz-implementation/ + +vector Solution::fizzBuzz(int A) { + vector v; + for(int i=1; i<=A; i++) + { + if(i%15==0) + v.push_back("FizzBuzz"); + else if(i%3==0) + v.push_back("Fizz"); + else if(i%5==0) + v.push_back("Buzz"); + else + v.push_back(to_string(i)); + } + return v; +} diff --git a/Math/LargestCoprimeDivisor.cpp b/Math/LargestCoprimeDivisor.cpp new file mode 100644 index 0000000..a83953b --- /dev/null +++ b/Math/LargestCoprimeDivisor.cpp @@ -0,0 +1,10 @@ +//reference: https://www.geeksforgeeks.org/largest-number-divides-x-co-prime-y/ +//Note: you can write the function for gcd [i'm using inbuilt gcd function in c++] + +int Solution::cpFact(int x, int y) { + + while (__gcd(x, y) != 1) { + x = x / __gcd(x, y); + } + return x; +} diff --git a/Math/NumbersOfLengthN.cpp b/Math/NumbersOfLengthN.cpp new file mode 100644 index 0000000..ab47920 --- /dev/null +++ b/Math/NumbersOfLengthN.cpp @@ -0,0 +1,50 @@ +int all(bool digits[], int B, int total) { + bool isZero = digits[0] ? 1 : 0; + long long int count = 1; + if (B == 1) { + return total; + } + count *= isZero ? total - 1 : total; + count *= pow(total, B - 1); + return count; +} +int compare(bool digits[], int B, int C, int total) { + string c = to_string(C); + vector count(10); + for (int i = 1; i < 10; i ++) { + count[i] = digits[i - 1] + count[i - 1]; + } + int dp[B + 1]; + dp[0] = 0; + bool flag = 1; + for (int i = 1; i <= B; i ++) { + dp[i] = dp[i - 1] * total; + if (flag || i == 1) { + int smallCount = count[c[i - 1] - '0']; + if (B != 1 && i == 1 && digits[0]) { + smallCount --; + } + dp[i] += smallCount; + if (!digits[c[i - 1] - '0']) { + flag = false; + } + } + } + return dp[B]; +} +int Solution::solve(vector &A, int B, int C) { + int length = log10(C) + 1; + bool digits[10] = {0}; + int total = 0; + for (int i = 0; i < A.size(); i ++) { + digits[A[i]] = 1; + total ++; + } + if (B > length || B == 0) { + return 0; + } else if (B < length) { + return all(digits, B, total); + } else { + return compare(digits, B, C, total); + } +} diff --git a/Math/SortedPermutationRank.cpp b/Math/SortedPermutationRank.cpp new file mode 100644 index 0000000..4693785 --- /dev/null +++ b/Math/SortedPermutationRank.cpp @@ -0,0 +1,46 @@ +#define mod 1000003 + +void buildFact(vector &fact,int len){ + fact.push_back(1); + fact.push_back(1); + for(int i = 2; i<= len ; i++){ + fact.push_back((fact[i-1]*i)%mod); + } +} + +int Solution::findRank(string A){ + vector fact; + // create a vector filled with factorial value of that index modulated + buildFact(fact,A.length()); + + // created a sorted version of given string + string b = A; + sort(b.begin() , b.end()); + + // create to Hash to store actual location of each character in sorted manner + unordered_map pos; + for(int i = 0; i v; + for(int i = 0; i v[i]) + v[j]--; + } + } + reverse(v.begin() , v.end()); + + // factorial arithmatics + long n = 0; + for(int i = 0; i < v.size() ; i++){ + n = (n + v[i]*fact[i])%mod; + } + n++; + return n; +} diff --git a/Math/SortedPermutationRankWithRepeats.cpp b/Math/SortedPermutationRankWithRepeats.cpp new file mode 100644 index 0000000..c42bdda --- /dev/null +++ b/Math/SortedPermutationRankWithRepeats.cpp @@ -0,0 +1,62 @@ +#define MOD 1000003 +long long int fact(int n) { + if (n == 0 || n == 1) { + return 1; + } + return (fact(n - 1) * n) % MOD; +} + long long int inverseNumber(int num) { + long long int ans = 1, base = (long long) num; + int power = MOD - 2; + while (power > 0) { + if (power == 1) { + return (ans * base) % MOD; + } + if (power % 2 == 0) { + base = (base * base) % MOD; + power /= 2; + } else { + ans = (ans * base) % MOD; + power--; + } + } + return ans; +} +int Solution::findRank(string A) { + if (A.size() <= 0) { + return 0; + } + int alpha[52] = {0}; + for (int i = 0; i < A.size(); i ++) { + if (islower(A[i])) { + alpha[A[i] - 'a' + 26] ++; + } else { + alpha[A[i] - 'A'] ++; + } + } + long long int total = 0; + for (int i = 0; i < A.size(); i ++) { + long long localCount = 0; + int size = islower(A[i]) ? A[i] - 'a' + 26 : A[i] - 'A'; + long long int count = (fact(A.size() - i - 1)); + for (int j = 0; j < size; j ++) { + if (alpha[j]) { + alpha[j] --; + localCount = count; + for (int k = 0; k < 52; k ++) { + if (alpha[k]) { + localCount = (localCount * inverseNumber(fact(alpha[k]))) % MOD; + } + } + alpha[j] ++; + total = (total + localCount) % MOD; + } + } + if (islower(A[i])) { + alpha[A[i] - 'a' + 26] --; + } else { + alpha[A[i] - 'A'] --; + } + } + return (total + 1) % MOD; +} diff --git a/Stacks-and-Queues/Simplify Directory Path.cpp b/Stacks-and-Queues/Simplify Directory Path.cpp new file mode 100644 index 0000000..4246dae --- /dev/null +++ b/Stacks-and-Queues/Simplify Directory Path.cpp @@ -0,0 +1,36 @@ +//https://www.interviewbit.com/problems/simplify-directory-path/ + +string Solution::simplifyPath(string A) { + stack st; + + int len = A.length(); + + for(int i=0;i='a' && A[l]<='z') && !(A[l]>='0' && A[l]<='9')) + { + l++; + } + + else if(!(A[h]>='a' && A[h]<='z') && !(A[h]>='0' && A[h]<='9')) + { + h--; + } + else if(A[l] == A[h]) + { + l++; + h--; + } + else + { + return 0; + } + } + + return 1; +} + +/* int Solution::isPalindrome(string A) { // Do not write main() function. // Do not read input, instead use the arguments to the function. @@ -85,3 +123,4 @@ int Solution::isPalindrome(string A) { return 1; } +*/ diff --git a/Strings/PrettyJson.cpp b/Strings/PrettyJson.cpp new file mode 100644 index 0000000..4957cff --- /dev/null +++ b/Strings/PrettyJson.cpp @@ -0,0 +1,60 @@ +vector Solution::prettyJSON(string A) +{ + int n = A.size(),i,j; + vector< string >ans; + int tbctr = 0; + i = 0; + bool flag = false; + while(i makeSieve(int n = 500) { + unordered_map umap; + vector num(n, 1); + for (int i = 2; i * i <= n; i ++) { + for (int j = 2; j * i <= n; j ++) { + num[i * j] = 0; + } + } + for (int i = 2; i < num.size(); i ++) { + if (num[i]) { + umap[i] = 0; + } + } + return umap; +} + +// Seperate the factors of the min. time to get LCM + +void seperateFactors(ll num, unordered_map &umap) { + for (auto it: umap) { + ll exponentVal = 0; + if (num % it.first == 0) { + while (num % it.first == 0) { + exponentVal ++; + num /= it.first; + } + if (exponentVal > it.second) { + umap[it.first] = exponentVal; + } + } + } + if (num != 1) { + umap[num] = 1; + } + return; +} + +// Driver + +int Solution::solve(vector &A) { + ll res = 1; + auto umap = makeSieve(); + for (int i = 0; i < A.size(); i ++) { + long long val = timeTaken(A[i]); + seperateFactors(val, umap); + } + for (auto it: umap) { + ll expVal = 1; + ll maxExp = it.second; + while (maxExp) { + expVal = (expVal * it.first) % MOD; + maxExp --; + } + res = (res * expVal) % MOD; + } + return res; +} \ No newline at end of file diff --git a/Strings/ValidIPAddresses.cpp b/Strings/ValidIPAddresses.cpp index 00a5bd1..f94148a 100644 --- a/Strings/ValidIPAddresses.cpp +++ b/Strings/ValidIPAddresses.cpp @@ -137,3 +137,51 @@ vector Solution::restoreIpAddresses(string A) { return sol; } + +// Alternate solution using recursion + +// Helper function to check validity of a string + +bool checkValidNum(string a) { + return a.size() > 1 && a[0] == '0' ? 0 : stoll(a) >= 0 && stoll(a) <= 255; +} + +// Helper function to check validity of a whole IP + +bool checkValidIP(string a) { + int occurences = count(a.begin(), a.end(), '.'); + if (occurences != 3) { + return 0; + } + int start = 0; + while (a.find('.', start) != string::npos) { + string temp = a.substr(start, a.find('.', start) - start); + if (!checkValidNum(temp)) { + return 0; + } + start = a.find('.', start) + 1; + } + return checkValidNum(a.substr(start)); +} + +// Helper function to generate all possibilities + +void generate (string A, vector &res, int index, string local) { + if (index >= A.size()) { + if (checkValidIP(local)) { + res.push_back(local); + } + return; + } + for (int i = 1; i <= A.size() - index; i ++) { + string temp = A.substr(index, i); + generate(A, res, index + i, local.size() ? local + "." + temp : temp); + } + return; +} +vector Solution::restoreIpAddresses(string A) { + vector res; + generate(A, res, 0, string()); + return res; +} + diff --git a/Trees/2-SumBinaryTree.cpp b/Trees/2-SumBinaryTree.cpp index 35fc495..d4dcfd2 100644 --- a/Trees/2-SumBinaryTree.cpp +++ b/Trees/2-SumBinaryTree.cpp @@ -9,72 +9,212 @@ * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ - +// A shorter and intuitive method. Check out the next two solutions as well. int Solution::t2Sum(TreeNode* A, int B) { + // Base Case + if(!A)return 0; - stack st1; - stack st2; - - int val1 = 0, val2 = 0; - int done1 = 0, done2 = 0; + // Make two stacks for the two different traversals, + // one from the right side, other from the left. + stack s1, s2; + TreeNode* temp1 = A, *temp2 = A; - TreeNode* curr1 = A; - TreeNode* curr2 = A; + // Take temp1 to the extreme left + while(temp1){ + s1.push(temp1); + temp1 = temp1->left; + } + // and temp2 to extreme right + while(temp2){ + s2.push(temp2); + temp2 = temp2->right; + } + temp1 = s1.top(); + temp2 = s2.top(); - while(1){ - while(done1 == 0){ - if(curr1 != NULL){ - st1.push(curr1); - curr1 = curr1->left; + // While we do not traverse the complete tree + while(temp1 and temp2 and temp1->val < temp2 -> val){ + if(temp1->val + temp2->val == B)return 1; + + if(temp1->val + temp2->val < B){ + // Move Ahead the temp1 pointer + s1.pop(); + // Check out the preorder traversal using stacks + temp1 = temp1->right; + while(temp1){ + s1.push(temp1); + temp1 = temp1->left; } - else{ - if(st1.empty()){ - done1 = 1; - } - else{ - curr1 = st1.top(); - val1 = curr1->val; - st1.pop(); - curr1 = curr1->right; - done1 = 1; - } + temp1 = s1.top(); + }else{ + // Move ahead the temp2 pointer + s2.pop(); + // Inverse of preorder traversal using stacks + // (not to be confused with postorder traversal) + temp2 = temp2->left; + while(temp2){ + s2.push(temp2); + temp2 = temp2->right; } + temp2 = s2.top(); } + } + return 0; +} + + +// int Solution::t2Sum(TreeNode* A, int B) { + +// stack st1; +// stack st2; + +// int val1 = 0, val2 = 0; +// int done1 = 0, done2 = 0; + +// TreeNode* curr1 = A; +// TreeNode* curr2 = A; + + +// while(1){ +// while(done1 == 0){ +// if(curr1 != NULL){ +// st1.push(curr1); +// curr1 = curr1->left; +// } +// else{ +// if(st1.empty()){ +// done1 = 1; +// } +// else{ +// curr1 = st1.top(); +// val1 = curr1->val; +// st1.pop(); +// curr1 = curr1->right; +// done1 = 1; +// } +// } +// } - while(done2 == 0){ - if(curr2 != NULL){ - st2.push(curr2); - curr2 = curr2->right; - } - else{ - if(st2.empty()){ - done2 = 1; - } - else{ - curr2 = st2.top(); - st2.pop(); - val2 = curr2->val; - curr2 = curr2->left; - done2 = 1; - } - } - } +// while(done2 == 0){ +// if(curr2 != NULL){ +// st2.push(curr2); +// curr2 = curr2->right; +// } +// else{ +// if(st2.empty()){ +// done2 = 1; +// } +// else{ +// curr2 = st2.top(); +// st2.pop(); +// val2 = curr2->val; +// curr2 = curr2->left; +// done2 = 1; +// } +// } +// } - if(((val1 + val2) == B) && (val1 != val2)){ - return 1; - } - else if((val1 + val2) < B){ - done1 = 0; - } - else if((val1 + val2) > B){ - done2 = 0; - } +// if(((val1 + val2) == B) && (val1 != val2)){ +// return 1; +// } +// else if((val1 + val2) < B){ +// done1 = 0; +// } +// else if((val1 + val2) > B){ +// done2 = 0; +// } - if(val1 >= val2){ - return 0; - } - } +// if(val1 >= val2){ +// return 0; +// } +// } - return 0; -} +// return 0; +// } + +/* +Another method if you are unable to get above method, although both of them work the same. +*/ + + +// bool isPairPresent(int K, TreeNode* A, TreeNode* B, stack s1, stack s2){ +// // Base Case +// if(!A)return 0; + +// // Go to the extreme left +// while(A){ +// s1.push(A); +// A = A ->left; +// } +// // Go to the extreme right +// while(B){ +// s2.push(B); +// B = B->right; +// } + +// Get the lowest and highest elements. +// A = s1.top(); s1.pop(); +// B = s2.top(); s2.pop(); + +// // Make the extremes as lowest and highest values (coz BST) +// int low = A->val, high = B->val; +// bool b1 = true; +// bool b2 = true; +// // While we don't cross the two pointers +// while(low < high){ +// // Return if we have found the sum +// if(low + high == K)return 1; +// // If the sum is less, increase the lower pointer only. +// if(low + high < K){ +// b2 = false; +// b1 = true; +// } +// // Else decrement the higher pointer only. +// else { +// b2 = true; +// b1 = false; +// } +// if(b1){ +// // If the pointer is not NULL, take it to the extreme left +// // of its right child +// if(A){ +// A = A->right; +// while(A){ +// s1.push(A); +// A = A->left; +// } +// } +// // Else just pop the top of the stack and make it as the lowest pointer. +// else { +// A = s1.top(); +// s1.pop(); +// low = A->val; +// } +// } +// // Same as above. +// else if(b2){ + +// if(B){ +// B = B->left; +// while(B){ +// s2.push(B); +// B = B->right; +// } +// }else { +// B = s2.top(); +// s2.pop(); +// high = B->val; +// } +// } +// } +// return 0; +// } + +// int Solution::t2Sum(TreeNode* A, int B) { +// stack s1, s2; + +// TreeNode *head1 = A, *head2 = A; + +// return isPairPresent(B, head1, head2, s1, s2); +// } diff --git a/Trees/BinaryTreeFromInorderAndPostorder.cpp b/Trees/BinaryTreeFromInorderAndPostorder.cpp new file mode 100644 index 0000000..743e93b --- /dev/null +++ b/Trees/BinaryTreeFromInorderAndPostorder.cpp @@ -0,0 +1,37 @@ +/** + * Definition for binary tree + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode(int x) : val(x), left(NULL), right(NULL) {} + * }; + */ +int search(vector &in, int str, int end, int val){ + for(int k=str; k<=end; k++) + if(in[k] == val) + return k; +} + +TreeNode* getTre(vector &post, vector &in, int start, int end, int &treeIndex){ + + if(start > end) + return NULL; + + TreeNode* node = new TreeNode(post[treeIndex--]); + + if(start == end) + return node; + + int root = search(in, start, end, node->val); + + node->right = getTre(post, in, root+1, end, treeIndex); + node->left = getTre(post, in, start, root-1, treeIndex); + + return node; +} + +TreeNode* Solution::buildTree(vector &in, vector &post) { + int treeIndex = in.size()-1; + return getTre(post, in, 0, in.size()-1, treeIndex); +} diff --git a/Trees/ConstructBinaryTreeFromInorderAndPreorder.cpp b/Trees/ConstructBinaryTreeFromInorderAndPreorder.cpp index 1076071..007d778 100644 --- a/Trees/ConstructBinaryTreeFromInorderAndPreorder.cpp +++ b/Trees/ConstructBinaryTreeFromInorderAndPreorder.cpp @@ -7,10 +7,10 @@ * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ -int index(vector v, int val, int start, int end){ +int index(vector &inorder, int val, int start, int end){ int i; for(i = start; i <= end; i++){ - if(v[i] == val){ + if(inorder[i] == val){ return i; } } diff --git a/Trees/HotelReviews.cpp b/Trees/HotelReviews.cpp new file mode 100644 index 0000000..2fbb1ba --- /dev/null +++ b/Trees/HotelReviews.cpp @@ -0,0 +1,115 @@ +struct TrieNode{ + bool isWord; + unordered_map children; + TrieNode(bool word): isWord(word) {} +}; + +struct res { + int index, score; +}; + +void tokenize (string good_string, vector &goodWords) { + good_string += "_"; + string temp=""; + + for (int i=0; i rhs.score) return true; + else if (lhs.score == rhs.score) return lhs.index < rhs.index; + return false; +} + +void constructTrie(TrieNode* A, vector goodWords) { + TrieNode* current = A; + + for (int i=0; ichildren).find(goodWords[i][j]); + + if (it != (current->children).end()) { + current = it->second; + } else { + + TrieNode* B = new TrieNode(false); + (current->children)[goodWords[i][j]] = B; + current = B; + + } + + if (j == goodWords[i].length()-1) current->isWord = true; + } + } + +} + +vector sortReviews(vector reviews, TrieNode* root) { + int score; + vector result; + TrieNode* current; + + vector temp; + + + + for (int i=0; ichildren).find(temp[j][k]); + if (it == (current->children).end()) { + break; + } + + current = it->second; + + if (k == temp[j].length()-1 && current->isWord) score++; + } + } + t.index = i; + t.score = score; + result.push_back(t); + } + + sort(result.begin(), result.end(), sortByScore); + + vector ret; + + for (int i=0; i Solution::solve(string A, vector &B) { + TrieNode* root = new TrieNode(false); + vector good_words; + + tokenize(A, good_words); + + constructTrie(root, good_words); + + vector result = sortReviews(B, root); + + return result; +} diff --git a/Trees/MinDepthOfABinaryTree.cpp b/Trees/MinDepthOfABinaryTree.cpp new file mode 100644 index 0000000..da628e5 --- /dev/null +++ b/Trees/MinDepthOfABinaryTree.cpp @@ -0,0 +1,7 @@ +int Solution::minDepth(TreeNode* A) { + if(!A)return 0; + if(!A->left and !A->right) return 1; + if(!A->left)return minDepth(A->right) + 1; + if(!A->right)return minDepth(A->left) + 1; + return min(minDepth(A->left), minDepth(A->right)) + 1; +} diff --git a/Trees/MinimumDepthOfABinaryTree.cpp b/Trees/MinimumDepthOfABinaryTree.cpp deleted file mode 100644 index 2eb4952..0000000 --- a/Trees/MinimumDepthOfABinaryTree.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// https://www.interviewbit.com/problems/min-depth-of-binary-tree/ - -/** - * Definition for binary tree - * struct TreeNode { - * int val; - * TreeNode *left; - * TreeNode *right; - * TreeNode(int x) : val(x), left(NULL), right(NULL) {} - * }; - */ -int depth(TreeNode* root){ - if(root == NULL){ - return 0; - } - else if(root->left == NULL && root->right == NULL){ - return 1; - } - else if(root->left == NULL && root->right != NULL){ - return 1 + depth(root->right); - } - else if(root->left != NULL && root->right == NULL){ - return 1 + depth(root->left); - } - return min(1 + depth(root->right), 1 + depth(root->left)); -} - -int Solution::minDepth(TreeNode* A) { - // Do not write main() function. - // Do not read input, instead use the arguments to the function. - // Do not print the output, instead return values as specified - // Still have a doubt. Checkout www.interviewbit.com/pages/sample_codes/ for more details - - return depth(A); - -} diff --git a/Trees/PopulateNextRightPointersTree.cpp b/Trees/PopulateNextRightPointersTree.cpp index c76b483..e7dbac0 100644 --- a/Trees/PopulateNextRightPointersTree.cpp +++ b/Trees/PopulateNextRightPointersTree.cpp @@ -6,47 +6,89 @@ * TreeLinkNode(int x) : val(x), left(NULL), right(NULL), next(NULL) {} * }; */ + +// A Non-recursive solution void Solution::connect(TreeLinkNode* A) { - if(A == NULL){ - return; - } + if(A == NULL)return; - if(A->left != NULL){ - if(A->right != NULL){ - (A->left)->next = A->right; - } - else{ - TreeLinkNode* temp = A; - while(temp->next != NULL){ - if((temp->next)->left != NULL){ - (A->left)->next = (temp->next)->left; - break; - } - else if((temp->next)->right != NULL){ - (A->left)->next = (temp->next)->right; - break; - } - temp = temp->next; - } + queue > q; + + q.push({0, A}); + + while(!q.empty()){ + pair temp = q.front(); + + int level = temp.first; + q.pop(); + +// Keep putting the nodes until we are on the same level. + while(!q.empty() and q.front().first == level){ + if(temp.second->left) + q.push({level+1, temp.second->left}); + if(temp.second->right) + q.push({level+1, temp.second->right}); + + temp.second->next = q.front().second; + temp = q.front(); + + q.pop(); } +// + temp.second->next = NULL; + +// if the control doesn't enter the above while loop, accomodate +// the left out nodes. (Consider a three node tree!) + if(temp.second->left) + q.push({level+1, temp.second->left}); + if(temp.second->right) + q.push({level+1, temp.second->right}); + } +} + + +// Recursive Solution +// void Solution::connect(TreeLinkNode* A) { +// if(A == NULL){ +// return; +// } - if(A->right != NULL){ - TreeLinkNode* temp = A; - while(temp->next != NULL){ - if((temp->next)->left != NULL){ - (A->right)->next = (temp->next)->left; - break; - } - else if((temp->next)->right != NULL){ - (A->right)->next = (temp->next)->right; - break; - } - temp = temp->next; - } - } +// if(A->left != NULL){ +// if(A->right != NULL){ +// (A->left)->next = A->right; +// } +// else{ +// TreeLinkNode* temp = A; +// while(temp->next != NULL){ +// if((temp->next)->left != NULL){ +// (A->left)->next = (temp->next)->left; +// break; +// } +// else if((temp->next)->right != NULL){ +// (A->left)->next = (temp->next)->right; +// break; +// } +// temp = temp->next; +// } +// } +// } +// if(A->right != NULL){ +// TreeLinkNode* temp = A; +// while(temp->next != NULL){ +// if((temp->next)->left != NULL){ +// (A->right)->next = (temp->next)->left; +// break; +// } +// else if((temp->next)->right != NULL){ +// (A->right)->next = (temp->next)->right; +// break; +// } +// temp = temp->next; +// } +// } - connect(A->right); - connect(A->left); -} + +// connect(A->right); +// connect(A->left); +// } diff --git a/Trees/VerticalOrderTraversalOfBinaryTree.cpp b/Trees/VerticalOrderTraversalOfBinaryTree.cpp index 72c68b1..336eaba 100644 --- a/Trees/VerticalOrderTraversalOfBinaryTree.cpp +++ b/Trees/VerticalOrderTraversalOfBinaryTree.cpp @@ -7,74 +7,103 @@ * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ -struct node{ - TreeNode* root; - int dis; -}; -void make(map >& m, queue& q){ - if(q.size() == 0){ - return; - } +vector > Solution::verticalOrderTraversal(TreeNode* A) { + vector > v; + if(A == NULL)return v; - TreeNode* root = (q.front()).root; - int dis = (q.front()).dis; + queue > q; + q.push({A, 0}); - if(!root){ - return; + map > mp; + while(!q.empty()){ + pair temp = q.front(); + q.pop(); + + if(temp.first->left){ + q.push({temp.first->left, temp.second-1}); + } + if(temp.first->right){ + q.push({temp.first->right, temp.second+1}); + } + + mp[temp.second].push_back(temp.first->val); + } + + for(map >::iterator it = mp.begin(); it != mp.end(); it++){ + v.push_back(it->second); } + return v; +} + +// struct node{ +// TreeNode* root; +// int dis; +// }; + +// void make(map >& m, queue& q){ +// if(q.size() == 0){ +// return; +// } - m[dis].push_back(root->val); +// TreeNode* root = (q.front()).root; +// int dis = (q.front()).dis; - q.pop(); +// if(!root){ +// return; +// } - if(root->left){ - node l1; - l1.root = root->left; - l1.dis = dis-1; - q.push(l1); - } +// m[dis].push_back(root->val); - if(root->right){ - node l1; - l1.root = root->right; - l1.dis = dis+1; - q.push(l1); - } +// q.pop(); - make(m, q); -} +// if(root->left){ +// node l1; +// l1.root = root->left; +// l1.dis = dis-1; +// q.push(l1); +// } + +// if(root->right){ +// node l1; +// l1.root = root->right; +// l1.dis = dis+1; +// q.push(l1); +// } + +// make(m, q); +// } -vector > Solution::verticalOrderTraversal(TreeNode* A) { - map > m; - vector > sol; - queue q; +// vector > Solution::verticalOrderTraversal(TreeNode* A) { +// map > m; +// vector > sol; +// queue q; - node n; - n.root = A; - n.dis = 0; +// node n; +// n.root = A; +// n.dis = 0; - q.push(n); +// q.push(n); - make(m, q); +// make(m, q); - map > :: iterator it = m.begin(); +// map > :: iterator it = m.begin(); - int curr = 0; +// int curr = 0; - while(it != m.end()){ - vector temp; - sol.push_back(temp); +// while(it != m.end()){ +// vector temp; +// sol.push_back(temp); - temp = it->second; +// temp = it->second; - for(int i = 0; i < temp.size(); i++){ - sol[curr].push_back(temp[i]); - } +// for(int i = 0; i < temp.size(); i++){ +// sol[curr].push_back(temp[i]); +// } - curr++; - it++; - } +// curr++; +// it++; +// } - return sol; -} +// return sol; +// } diff --git a/Two-Pointers/3Sum.cpp b/Two-Pointers/3Sum.cpp index 412b4ba..3e9b70d 100644 --- a/Two-Pointers/3Sum.cpp +++ b/Two-Pointers/3Sum.cpp @@ -14,7 +14,6 @@ int Solution::threeSumClosest(vector &A, int B) { int i = 0; int sum, minDiff = INT_MAX; - int count = 0; while(i < A.size()-2){ int left = i+1; diff --git a/Two-Pointers/3SumZero.cpp b/Two-Pointers/3SumZero.cpp index 63cc4eb..a4d019d 100644 --- a/Two-Pointers/3SumZero.cpp +++ b/Two-Pointers/3SumZero.cpp @@ -1,70 +1,106 @@ -// https://www.interviewbit.com/problems/3-sum-zero/ - vector > Solution::threeSum(vector &A) { - // Do not write main() function. - // Do not read input, instead use the arguments to the function. - // Do not print the output, instead return values as specified - // Still have a doubt. Checkout www.interviewbit.com/pages/sample_codes/ for more details + vector > v; + + if(A.size() == 0)return v; - vector > sol; + vector > v1(A.size()); - if(A.size() < 2){ - return sol; + for(int i = 0; i < A.size(); i++){ + v1[i] = {A[i], i}; } - sort(A.begin(), A.end()); + sort(v1.begin(), v1.end()); - int i = 0; + set > mp; - while(i < A.size()-2){ + for(int i = 0; i < A.size(); i++){ + int firset = v1[i].first; int j = i+1; int k = A.size()-1; - LOOP:while(j < k){ - int sum = A[i] + A[j] + A[k]; - if(sum == 0){ - vector temp; - temp.push_back(A[i]); - temp.push_back(A[j]); - temp.push_back(A[k]); - sol.push_back(temp); - temp.erase(temp.begin(),temp.end()); - while(A[j] == A[j+1]){ - j++; - if(j == A.size()){ - break; - } - } - j++; - } - else if(sum > 0){ - while(A[k] == A[k-1]){ - k--; - if(k == 0){ - break; - } - } - k--; - } - else{ - while(A[j] == A[j+1]){ - j++; - if(j == A.size()){ - break; - } + while(j < k){ + if(v1[j].first + v1[k].first + firset == 0){ + vector v2({A[v1[i].second], A[v1[j].second], A[v1[k].second]}); + sort(v2.begin(), v2.end()); + if(mp.find(v2) == mp.end()){ + v.push_back(v2); + mp.insert(v2); } + j++; k--; + }else if(v1[j].first + v1[k].first + firset < 0){ j++; - } - - } - while(A[i+1] == A[i]){ - i++; - if(i == A.size()-1){ - return sol; - } + }else k--; } - i++; } + return v; +} + +// // https://www.interviewbit.com/problems/3-sum-zero/ + +// vector > Solution::threeSum(vector &A) { +// // Do not write main() function. +// // Do not read input, instead use the arguments to the function. +// // Do not print the output, instead return values as specified +// // Still have a doubt. Checkout www.interviewbit.com/pages/sample_codes/ for more details - return sol; +// vector > sol; -} +// if(A.size() < 2){ +// return sol; +// } + +// sort(A.begin(), A.end()); + +// int i = 0; + +// while(i < A.size()-2){ +// int j = i+1; +// int k = A.size()-1; +// LOOP:while(j < k){ +// int sum = A[i] + A[j] + A[k]; +// if(sum == 0){ +// vector temp; +// temp.push_back(A[i]); +// temp.push_back(A[j]); +// temp.push_back(A[k]); +// sol.push_back(temp); +// temp.erase(temp.begin(),temp.end()); +// while(A[j] == A[j+1]){ +// j++; +// if(j == A.size()){ +// break; +// } +// } +// j++; +// } +// else if(sum > 0){ +// while(A[k] == A[k-1]){ +// k--; +// if(k == 0){ +// break; +// } +// } +// k--; +// } +// else{ +// while(A[j] == A[j+1]){ +// j++; +// if(j == A.size()){ +// break; +// } +// } +// j++; +// } + +// } +// while(A[i+1] == A[i]){ +// i++; +// if(i == A.size()-1){ +// return sol; +// } +// } +// i++; +// } + +// return sol; + +// } diff --git a/Two-Pointers/SortByColor.cpp b/Two-Pointers/SortByColor.cpp new file mode 100644 index 0000000..7f13b18 --- /dev/null +++ b/Two-Pointers/SortByColor.cpp @@ -0,0 +1,37 @@ +// https://www.interviewbit.com/problems/sort-by-color/ + +void Solution::sortColors(vector &A) { + // Do not write main() function. + // Do not read input, instead use the arguments to the function. + // Do not print the output, instead return values as specified + // Still have a doubt. Checkout www.interviewbit.com/pages/sample_codes/ for more details + + int lo = 0; + int hi = A.size() - 1; + int mid = 0; + + // Iterate till all the elements + // are sorted + while (mid <= hi) + { + switch (A[mid]) + { + + // If the element is 0 + case 0: + swap(A[lo++], A[mid++]); + break; + + // If the element is 1 . + case 1: + mid++; + break; + + // If the element is 2 + case 2: + swap(A[mid], A[hi--]); + break; + } + } + +} \ No newline at end of file