Repository: coding-minutes/dsa-essentials-solutions-cpp Branch: master Commit: 03d2b96551a0 Files: 76 Total size: 53.1 KB Directory structure: gitextract_2mb6elmx/ └── DSA Essentials Solutions/ ├── 2d Arrays/ │ ├── PascalsTriangle.cpp │ ├── SubmatrixSum.cpp │ └── WavePrint.cpp ├── Arrays/ │ ├── K-rotate.cpp │ ├── LargestElement.cpp │ ├── LowerBound.cpp │ ├── MaximumSumSubarray.cpp │ └── SortedPairSum.cpp ├── Backtracking/ │ ├── N-QueenWays.cpp │ ├── RatAndMice.cpp │ ├── UniqueSubset.cpp │ ├── WordBreakProblem.cpp │ └── WordSearch.cpp ├── Basic Sorting Algorithms/ │ ├── Chopsticks.cpp │ ├── DefenseKingdom.cpp │ ├── OptimisedBubbleSort.cpp │ ├── SortingCartesianProducts.cpp │ └── SortingWithComparator.cpp ├── BinarySearchTree/ │ ├── DeleteInBST.cpp │ ├── IsBST.cpp │ └── MirrorABST.cpp ├── BinaryTree/ │ ├── ExpressionTree.cpp │ ├── K-thLevel.cpp │ ├── MinDepth.cpp │ ├── RemoveHalfNodes.cpp │ ├── SumOfNodes.cpp │ ├── SymmetricTree.cpp │ └── TargetPathSum.cpp ├── Bit Manipulation/ │ ├── EarthLevels.cpp │ ├── ModuloExponentiation.cpp │ ├── SubsetSumQueries.cpp │ └── Xoring.cpp ├── Divide and Conquer/ │ ├── 2DArrayMerge.cpp │ └── BinarySearchUsingRecursion.cpp ├── Dynamic Programming/ │ ├── CoinChange.cpp │ ├── MinimumPartitioning.cpp │ ├── OptimalGameStrategy.cpp │ └── Vacation.cpp ├── Graphs/ │ ├── AllPathsFromSourceToTarget.cpp │ ├── FindStarInGraph.cpp │ └── KeysAndRooms.cpp ├── Hashing/ │ ├── ArrayIntersection.cpp │ └── KSumSubarray.cpp ├── Heaps/ │ ├── MaximumProduct.cpp │ ├── ReduceArraySizeToHalf.cpp │ ├── RelativeRanks.cpp │ └── WeakestRows.cpp ├── Linked List/ │ ├── AlternateMerge.cpp │ ├── BubbleSortOnLinkedList.cpp │ ├── DeleteTail.cpp │ └── KthLastElement.cpp ├── Queues/ │ ├── FirstNonRepeatingLetter.cpp │ ├── InterleaveTwoHalvesOfQueue.cpp │ └── SortQueueWithConstantSpace.cpp ├── Recursion/ │ ├── 2DArrayMerge.cpp │ ├── AllOccurences.cpp │ ├── BinaryStrings.cpp │ ├── FriendsParty.cpp │ ├── PrintIncreasingNumbers.cpp │ └── TilingProblem.cpp ├── Stacks/ │ ├── DuplicateParenthesis.cpp │ ├── MaximumRectangularAreaInHistogram.cpp │ ├── NextGreaterElement.cpp │ ├── ReverseANumberUsingStack.cpp │ └── StockSpanProblem.cpp ├── Strings/ │ ├── ArePermutation.cpp │ ├── BinaryStringToNumber.cpp │ ├── CheckPalindrome.cpp │ ├── RemoveDuplicates.cpp │ ├── StringCompression.cpp │ └── VowelFind.cpp ├── Trie/ │ └── PrefixStrings.cpp └── Vectors/ ├── MakeZeroes.cpp ├── RotateImage.cpp ├── SortFruits.cpp └── SortingCabs.cpp ================================================ FILE CONTENTS ================================================ ================================================ FILE: DSA Essentials Solutions/2d Arrays/PascalsTriangle.cpp ================================================ //Expected Time Complexity: O(n^3) //Hint: Use Binomial Coeffiecients #include using namespace std; int binomialCoeff(int n, int k); // Function to print first // n lines of Pascal's // Triangle vector> printPascal(int n) { // Iterate through every line and // print entries in it vector> res; for (int line = 0; line < n; line++) { // Every line has number of // integers equal to line // number vector v; for (int i = 0; i <= line; i++) {v.push_back(binomialCoeff(line, i));} res.push_back(v); } return res; } int binomialCoeff(int n, int k) { int res = 1; if (k > n - k) k = n - k; for (int i = 0; i < k; ++i) { res *= (n - i); res /= (i + 1); } return res; } ================================================ FILE: DSA Essentials Solutions/2d Arrays/SubmatrixSum.cpp ================================================ //Hint: Pre Compute Cumilative Sums of every index i,j. //Expected Time Complexity: // Pre Computing : O(N^2) // Queries: O(1) #include using namespace std; int sum(vector> v, int sr, int sc, int er, int ec){ int m=v.size(); int n=v[0].size(); // // int aux[m][n]; int M=m; int N=n; vector> aux = v; vector> mat = v; int tli=sr, tlj=sc, rbi=er, rbj=ec; for (int i=0; i 0) res = res - aux[tli-1][rbj]; // Remove elements between (0, 0) and (rbi, tlj-1) if (tlj > 0) res = res - aux[rbi][tlj-1]; // Add aux[tli-1][tlj-1] as elements between (0, 0) // and (tli-1, tlj-1) are subtracted twice if (tli > 0 && tlj > 0) res = res + aux[tli-1][tlj-1]; return res; } ================================================ FILE: DSA Essentials Solutions/2d Arrays/WavePrint.cpp ================================================ //Expected Time Complexity: O(n^2) #include using namespace std; vector WavePrint(int m, int n, vector> arr) { vector res; int i, j = n - 1, wave = 1; /* m - Ending row index n - Ending column index i, j - Iterator wave - for Direction wave = 1 - Wave direction down wave = 0 - Wave direction up */ while (j >= 0) { // Check whether to go in // upward or downward if (wave == 1) { // Print the element of the matrix // downward since the value of wave = 1 for (i = 0; i < m; i++) res.push_back(arr[i][j]); wave = 0; j--; } else { // Print the elements of the // matrix upward since the value // of wave = 0 for (i = m - 1; i >= 0; i--) res.push_back(arr[i][j]) ; wave = 1; j--; } } return res; } ================================================ FILE: DSA Essentials Solutions/Arrays/K-rotate.cpp ================================================ //Expected Time Complexity: O(n) #include using namespace std; vector kRotate(vector a, int k) { vector v; int n = a.size(); k = k % n; for(int i = 0; i < n; i++) { if(i < k) { v.push_back(a[n + i - k]); } else { v.push_back(a[i - k]); } } return v; } ================================================ FILE: DSA Essentials Solutions/Arrays/LargestElement.cpp ================================================ //Expected Time Complexity: O(N) #include using namespace std; int largestElement(vector A) { int largestEle = INT_MIN; for (auto element : A ) { largestEle = max(largestEle, element); } return largestEle; } ================================================ FILE: DSA Essentials Solutions/Arrays/LowerBound.cpp ================================================ //Expected Time Complexity: O(logN) //Hint: Binary Search #include using namespace std; int lowerBound(vector A, int Val) { int sz = A.size(); int l = 0, r = (sz-1); int answer = -1; while (l <= r) { int mid = (l + r) / 2; if (A[mid] > Val) { r = mid-1; } else { answer = A[mid]; l = mid+1; } } return answer; } ================================================ FILE: DSA Essentials Solutions/Arrays/MaximumSumSubarray.cpp ================================================ //Time complexity: O(n) //Hint: Kadane's Algorithm #include using namespace std ; int maxSumSubarray(vector A) { int n = A.size(), max_sum = *min_element(A.begin(), A.end()), curr_sum = 0; for(int i = 0 ; i < n ; i++){ if(curr_sum + A[i] <= 0){ curr_sum = A[i]; }else{ curr_sum += A[i]; } max_sum = max(max_sum, curr_sum); } return max_sum; } ================================================ FILE: DSA Essentials Solutions/Arrays/SortedPairSum.cpp ================================================ //Expected Time Complexity: O(N) //Hint: Two Pointer Approach #include using namespace std; pair closestSum(vector arr, int x){ int res_l, res_r; int n = arr.size(); int l = 0, r = n-1, diff = INT_MAX; while (r > l) { if (abs(arr[l] + arr[r] - x) < diff) { res_l = l; res_r = r; diff = abs(arr[l] + arr[r] - x); } if (arr[l] + arr[r] > x) r--; else l++; } return {arr[res_l], arr[res_r]}; } ================================================ FILE: DSA Essentials Solutions/Backtracking/N-QueenWays.cpp ================================================ #include using namespace std; int cnt; int isSafe(int N, int mat[][20], int r, int c) { // return 0 if two queens share the same column for (int i = 0; i < r; i++) { if (mat[i][c] == 1) { return 0; } } // return 0 if two queens share the same `` diagonal for (int i = r, j = c; i >= 0 && j >= 0; i--, j--) { if (mat[i][j] == 1) { return 0; } } // return 0 if two queens share the same `/` diagonal for (int i = r, j = c; i >= 0 && j < N; i--, j++) { if (mat[i][j] == 1) { return 0; } } return 1; } void solve(int N,int mat[][20], int r) { // if `N` queens are placed successfully, print the solution if (r == N) { cnt++; return; } // place queen at every square in the current row `r` // and recur for each valid movement for (int i = 0; i < N; i++) { // if no two queens threaten each other if (isSafe(N, mat, r, i)) { // place queen on the current square mat[r][i] = 1; // recur for the next row solve(N,mat, r + 1); // backtrack and remove the queen from the current square mat[r][i] = 0; } } } int nQueen(int n){ cnt =0; int arr[20][20]={0}; solve(n,arr,0); return cnt; } ================================================ FILE: DSA Essentials Solutions/Backtracking/RatAndMice.cpp ================================================ #include using namespace std; void ratchase(vector a,vector> &b,vector> &v,int i,int j,int n,int m){ if(i==n && j==m){ for(int k=0;k<=n;k++){ for(int l=0;l<=m;l++){ v[k][l] = b[k][l]; }cout<0 && a[i-1][j]!='X' && b[i-1][j]!=1){ b[i-1][j]=1; ratchase(a,b,v,i-1,j,n,m); b[i-1][j]=0; } if(j!=m && a[i][j+1]!='X' && b[i][j+1]!=1){ b[i][j+1]=1; ratchase(a,b,v,i,j+1,n,m); b[i][j+1]=0; } if(j>0 && a[i][j-1]!='X' && b[i][j-1]!=1){ b[i][j-1]=1; ratchase(a,b,v,i,j-1,n,m); b[i][j-1]=0; } return; } vector> ratAndMice(vector a) { int n = a.size(); int m = a[0].size(); vector> v(n, vector(m, 0)); vector> b(n, vector(m, 0)); b[0][0] = 1; ratchase(a,b,v,0,0,n-1,m-1); return v; } ================================================ FILE: DSA Essentials Solutions/Backtracking/UniqueSubset.cpp ================================================ #include using namespace std; set> s; void recur(vector &nums, vector ans, int i) { if(i == nums.size()){ sort(ans.begin(), ans.end()); s.insert(ans); return; } ans.push_back(nums[i]); recur(nums, ans, i+1); ans.pop_back(); recur(nums, ans, i+1); } vector> uniqueSubsets(vector nums){ s.clear(); vector ans; recur(nums, ans, 0); vector> v; for(auto x : s) v.push_back(x); return v; } ================================================ FILE: DSA Essentials Solutions/Backtracking/WordBreakProblem.cpp ================================================ #include using namespace std; int cnt = 0; vector v; void help(string s, int n, string res, vector &word) { for (int i = 1; i <= n; i++) { string ss = s.substr(0, i); int l = word.size(); bool flag = false; for (int j = 0; j < l; j++) if (word[j] == ss) flag = true; if (flag) { if (i == n) { res += ss; // v.push_back(res); cnt++; return; } help(s.substr(i, n - i), n - i, res + ss + " ", word); } } } int wordBreak(string s, vector &dictionary) { cnt = 0; // v.clear(); help(s, s.size(), "", dictionary); // for (auto x : v) cout << x << '\n'; return cnt; } ================================================ FILE: DSA Essentials Solutions/Backtracking/WordSearch.cpp ================================================ #include using namespace std; bool chk; void recur(vector>& board, string &word, int i, int j, int k) { if(k == word.size()) { chk = true; return; } if(i < 0 || j < 0 || i == board.size() || j == board[0].size() || board[i][j] == '-1') return; if(board[i][j] == word[k]) { char c = board[i][j]; board[i][j] = '-1'; recur(board, word, i, j+1, k+1); recur(board, word, i+1, j, k+1); recur(board, word, i, j-1, k+1); recur(board, word, i-1, j, k+1); board[i][j] = c; } return; } bool wordSearch(vector> &board, string word) { chk = false; for(int i=0; i using namespace std; int pairSticks(vector length, int D) { // your code goes here sort(length.begin(), length.end()); int res = 0; for(int i=0; i using namespace std; using ll = long long; #define all(v) v.begin(), v.end() int defkin(int W, int H, vector> position) { // your code goes here vector> v = position; int w = W, h = H; vector x, y; x.push_back(0); y.push_back(0); ll maxx = INT_MIN, maxy = INT_MIN; for(int i=0; i using namespace std; vector optimizedBubbleSort(vector arr){ // your code goes here int i, j, n=arr.size(); bool swapped; for (i = 0; i < n-1; i++) { swapped = false; for (j = 0; j < n-i-1; j++) { if (arr[j] > arr[j+1]) { swap(arr[j], arr[j+1]); swapped = true; } } // IF no two elements were swapped by inner loop, then break if (swapped == false) break; } return arr; } ================================================ FILE: DSA Essentials Solutions/Basic Sorting Algorithms/SortingCartesianProducts.cpp ================================================ //Expected Time Complexity :O(N log N) #include using namespace std; vector> sortCartesian(vector> v) { sort(v.begin(), v.end()); return v; } ================================================ FILE: DSA Essentials Solutions/Basic Sorting Algorithms/SortingWithComparator.cpp ================================================ #include using namespace std; bool compare(int a, int b){ return a > b; } vector sortingWithComparator(vector v, bool flag){ // your code goes here if(flag) sort(v.begin(), v.end()); else sort(v.begin(), v.end(), compare); return v; } ================================================ FILE: DSA Essentials Solutions/BinarySearchTree/DeleteInBST.cpp ================================================ #include using namespace std; class node{ public: int data; node*left; node*right; node(int d){ data=d; left=NULL; right=NULL; } }; node* deleteNode(node* root, int k){ // Base case if (root == NULL) return root; // Recursive calls for ancestors of // node to be deleted if (root->data > k) { root->left = deleteNode(root->left, k); return root; } else if (root->data < k) { root->right = deleteNode(root->right, k); return root; } // We reach here when root is the node // to be deleted. // If one of the children is empty if (root->left == NULL) { node* temp = root->right; delete root; return temp; } else if (root->right == NULL) { node* temp = root->left; delete root; return temp; } // If both children exist else { node* succParent = root; // Find successor node* succ = root->right; while (succ->left != NULL) { succParent = succ; succ = succ->left; } // Delete successor. Since successor // is always left child of its parent // we can safely make successor's right // right child as left of its parent. // If there is no succ, then assign // succ->right to succParent->right if (succParent != root) succParent->left = succ->right; else succParent->right = succ->right; // Copy Successor Data to root root->data = succ->data; // Delete Successor and return root delete succ; return root; } } ================================================ FILE: DSA Essentials Solutions/BinarySearchTree/IsBST.cpp ================================================ #include using namespace std; class Node { public: int key; Node *left; Node *right; Node(int key){ this->key = key; left = right = NULL; } }; bool isBSTUtil(Node* node, int min, int max) { /* an empty tree is BST */ if (node==NULL) return true; /* false if this node violates the min/max constraint */ if (node->key < min || node->key > max) return false; /* otherwise check the subtrees recursively, tightening the min or max constraint */ return isBSTUtil(node->left, min, node->key) && isBSTUtil(node->right, node->key, max); } bool isBST(Node * root){ //complete this method return isBSTUtil(root, INT_MIN,INT_MAX); } ================================================ FILE: DSA Essentials Solutions/BinarySearchTree/MirrorABST.cpp ================================================ #include using namespace std; class Node { public: int key; Node *left; Node *right; Node(int key){ this->key = key; left = right = NULL; } }; void mirror(Node* node) { if (node == NULL) return; else { struct Node* temp; /* do the subtrees */ mirror(node->left); mirror(node->right); /* swap the pointers in this node */ temp = node->left; node->left = node->right; node->right = temp; } } Node* mirrorBST(Node * root){ //complete this method mirror(root); return root; } ================================================ FILE: DSA Essentials Solutions/BinaryTree/ExpressionTree.cpp ================================================ //Expected Time Complexity: O(n) #include using namespace std; struct Node { string key; Node* left, *right; }; bool isOp(string data) { if(data == "+" or data == "-" or data == "*" or data == "/") return true; return false; } int evalTree(Node* root){ if(root == NULL) return 0; if(!isOp(root->key)) return stoi(root->key); if(root->key == "+") return evalTree(root->left)+evalTree(root->right); if(root->key == "-") return evalTree(root->left)-evalTree(root->right); if(root->key == "*") return evalTree(root->left)*evalTree(root->right); if(root->key == "/") return evalTree(root->left)/evalTree(root->right); } ================================================ FILE: DSA Essentials Solutions/BinaryTree/K-thLevel.cpp ================================================ //Expected Time Complexity: O(n) #include using namespace std; struct Node { int key; Node* left, *right; }; vector printKthLevel(Node* root, int k){ // your code goes here // Create Queue queue que; // Enqueue the root node que.push(root); // Create a set vector s; // Level to track // the current level int level = 0; int flag = 0; // Iterate the queue till its not empty while (!que.empty()) { // Calculate the number of nodes // in the current level int size = que.size(); // Process each node of the current // level and enqueue their left // and right child to the queue while (size--) { struct Node* ptr = que.front(); que.pop(); // If the current level matches the // required level then add into set if (level == k) { // Flag initialized to 1 flag = 1; // Inserting node data in set s.push_back(ptr->key); } else { // Traverse to the left child if (ptr->left) que.push(ptr->left); // Traverse to the right child if (ptr->right) que.push(ptr->right); } } // Increment the variable level // by 1 for each level level++; // Break out from the loop // if the Kth Level is reached if (flag == 1) break; } return s; } ================================================ FILE: DSA Essentials Solutions/BinaryTree/MinDepth.cpp ================================================ #include using namespace std; struct Node { int key; Node* left, *right; }; int minDepth(Node *root) { // Your code here int res = INT_MAX; queue> q; int d = 1; q.push({root, d}); while(!q.empty()) { Node* f = q.front().first; d = 1+q.front().second; if(f->left == NULL && f->right == NULL) res = min(res, q.front().second); q.pop(); if(f->left) q.push({f->left, d}); if(f->right) q.push({f->right, d}); } return res; } ================================================ FILE: DSA Essentials Solutions/BinaryTree/RemoveHalfNodes.cpp ================================================ #include using namespace std; struct Node { int key; Node* left, *right; }; void inorder(Node* root, vector &v) { if(root == NULL) return; if(root->left) inorder(root->left, v); v.push_back(root->key); if(root->right) inorder(root->right, v); } Node *help(Node *root) { //add code here. if(root==NULL) return NULL; if(root->right) root->right = help(root->right); if(root->left) root->left = help(root->left); if( (root->left != NULL && root->right == NULL) or (root->left == NULL && root->right !=NULL) ) { if(root->left) root = root->left; else root = root->right; root = help(root); } return root; } vector removeHalfNodes(Node *root) { //add code here. root = help(root); vector v; inorder(root, v); return v; } ================================================ FILE: DSA Essentials Solutions/BinaryTree/SumOfNodes.cpp ================================================ #include using namespace std; struct Node { int key; Node* left, *right; }; int sumBT(Node* root) { // Code here int res = 0; queue q; q.push(root); while(!q.empty()) { Node* f = q.front(); q.pop(); if(f->left) q.push(f->left); if(f->right) q.push(f->right); res += f->key; } return res; } ================================================ FILE: DSA Essentials Solutions/BinaryTree/SymmetricTree.cpp ================================================ #include using namespace std; struct Node { int key; Node* left, *right; }; bool isSymmetric(Node* root) { queue q1; queue q2; if(root == NULL || (root->right==NULL && root->left==NULL)) return true; if(root->right == NULL || root->left == NULL) return false; q1.push(root->left); q2.push(root->right); while(!q1.empty() && !q2.empty()) { Node* f1 = q1.front(); q1.pop(); Node* f2 = q2.front(); q2.pop(); if(q1.empty() && !q2.empty()) return false; if(!q1.empty() && q2.empty()) return false; if(f1->left==NULL && f2->right!=NULL) return false; if(f1->left!=NULL && f2->right==NULL) return false; if(f1->key != f2->key) return false; if(f1->left) q1.push(f1->left); if(f1->right) q1.push(f1->right); if(f2->right) q2.push(f2->right); if(f2->left) q2.push(f2->left); } if(q1.empty() && q2.empty()) return true; return false; } ================================================ FILE: DSA Essentials Solutions/BinaryTree/TargetPathSum.cpp ================================================ #include using namespace std; struct Node { int val; Node* left, *right; }; vector> vv; void help(Node* root, int a, vector &v, int b) { if(root == NULL) return; if(root->left == NULL && root->right == NULL) { if(a == b+root->val) { v.push_back(root->val); vv.push_back(v); v.pop_back(); } return; } if(root->left) { v.push_back(root->val); help(root->left, a, v, b+root->val); v.pop_back(); } if(root->right) { v.push_back(root->val); help(root->right, a, v, b+root->val); v.pop_back(); } } vector> pathSum(Node* root, int targetSum) { vv.clear(); vector v; help(root, targetSum, v, 0); return vv; } ================================================ FILE: DSA Essentials Solutions/Bit Manipulation/EarthLevels.cpp ================================================ // Expected Time Complexity : O(Log n) #include using namespace std; long long convertDecimalToBinary(unsigned long long int n) { long long binaryNumber = 0; unsigned long long int remainder, i = 1, step = 1; while (n!=0) { remainder = n%2; n /= 2; binaryNumber += remainder*i; i *= 10; } return binaryNumber; } int earthLevel(int k) { //your code goes here unsigned long long int binaryNumber, sum = 0; binaryNumber = convertDecimalToBinary(k); while (binaryNumber != 0) { unsigned long long int t; t = binaryNumber%2; sum = sum + t; binaryNumber = binaryNumber/10; } return sum; } ================================================ FILE: DSA Essentials Solutions/Bit Manipulation/ModuloExponentiation.cpp ================================================ // Expected Time Complexity : O(Log N) // Hint: if a is even, than x^a can be written as (x^(a/2))*(x^(a/2)) #include using namespace std; int power(int x, int y, int p) { int res = 1; // Initialize result x = x % p; // Update x if it is more than or // equal to p if (x == 0) return 0; // In case x is divisible by p; while (y > 0) { // If y is odd, multiply x with result if (y & 1) res = (res*x) % p; // y must be even now y = y>>1; // y = y/2 x = (x*x) % p; } return res; } ================================================ FILE: DSA Essentials Solutions/Bit Manipulation/SubsetSumQueries.cpp ================================================ // Expected Time Complexity : O(1) for each query #include using namespace std; vector subsetSum(vector v, vector q) { int n = q.size(); vector b(n); bitset<10000> bit; bit.reset(); bit[0] = 1; for (int i = 0; i < v.size(); ++i) bit |= (bit << v[i]); for(int i=0; i using namespace std; int xoring(vector v) { int res=0; for(auto x : v) res ^= x; return res; } ================================================ FILE: DSA Essentials Solutions/Divide and Conquer/2DArrayMerge.cpp ================================================ #include using namespace std; void merge_row(vector> &mat,int i, int cs, int cm, int ce){ vector sorted; int x=cs; int y=cm+1; //cout<> &mat,int j, int rs, int rm, int re){ vector sorted; int x=rs; int y=rm+1; while(x<=rm && y<=re){ if(mat[x][j]> &mat, int rs, int rm, int re,int cs, int cm, int ce){ //for sorting rows for(int i=rs; i<=re; i++){ merge_row(mat,i,cs,cm,ce); } //for sorting columns for(int j=cs; j<=ce; j++){ merge_col(mat,j,rs,rm,re); } return; } void merge_sort(int m, int n, vector> &mat, int rs, int re, int cs, int ce){ //cout<=re && cs>=ce){ return; } int rm=(rs+re)/2; int cm=(cs+ce)/2; // cout<> mergeSort(int m, int n, vector> v){ merge_sort(m,n,v,0,m-1,0,n-1); return v; } ================================================ FILE: DSA Essentials Solutions/Divide and Conquer/BinarySearchUsingRecursion.cpp ================================================ //Expected Time Complexity: O(logn) #include using namespace std; #include using namespace std; // A recursive binary search function. It returns // location of x in given array arr[l..r] is present, // otherwise -1 int binary(vector arr, int l, int r, int x) { if (r >= l) { int mid = l + (r - l) / 2; // If the element is present at the middle // itself if (arr[mid] == x) return mid; // If element is smaller than mid, then // it can only be present in left subarray if (arr[mid] > x) return binary(arr, l, mid - 1, x); // Else the element can only be present // in right subarray return binary(arr, mid + 1, r, x); } // We reach here when element is not // present in array return -1; } int binarySearch(vector v, int x) { // your code goes here int n = v.size(); int result = binary(v, 0, n - 1, x); return result; } ================================================ FILE: DSA Essentials Solutions/Dynamic Programming/CoinChange.cpp ================================================ #include using namespace std; long long coinChange(int s, int n , vector a, long long dp[500][100]) { if (n < 0 || s < 0) return 0; if (s == 0) return 1; if (dp[s][n] != 0) return dp[s][n]; long long op1 = coinChange(s, n - 1, a, dp); long long op2 = coinChange(s - a[n], n, a, dp); return dp[s][n] = op1 + op2; } long long findCombinations(int n, vector coins) { long long dp[500][100] = {{0}}; return coinChange(n, coins.size()-1, coins, dp); } ================================================ FILE: DSA Essentials Solutions/Dynamic Programming/MinimumPartitioning.cpp ================================================ #include using namespace std; int findMin(vector arr) { int n = arr.size(); int sum = 0; for (int i = 0; i < n; i++) sum += arr[i]; // Create an array to store results of subproblems bool dp[n + 1][sum + 1]; // Initialize first column as true. 0 sum is possible // with all elements. for (int i = 0; i <= n; i++) dp[i][0] = true; // Initialize top row, except dp[0][0], as false. With // 0 elements, no other sum except 0 is possible for (int i = 1; i <= sum; i++) dp[0][i] = false; // Fill the partition table in bottom up manner for (int i = 1; i <= n; i++) { for (int j = 1; j <= sum; j++) { // If i'th element is excluded dp[i][j] = dp[i - 1][j]; // If i'th element is included if (arr[i - 1] <= j) dp[i][j] |= dp[i - 1][j - arr[i - 1]]; } } // Initialize difference of two sums. int diff = INT_MAX; // Find the largest j such that dp[n][j] // is true where j loops from sum/2 t0 0 for (int j = sum / 2; j >= 0; j--) { // Find the if (dp[n][j] == true) { diff = sum - 2 * j; break; } } return diff; } ================================================ FILE: DSA Essentials Solutions/Dynamic Programming/OptimalGameStrategy.cpp ================================================ #include using namespace std; int game(int n, vector v, int s, int e){ if(s==e || s==e-1){ return max(v[s],v[e]); } int op1=v[s] + min(game(n,v,s+2,e),game(n,v,s+1,e-1)); int op2=v[e] + min(game(n,v,s+1,e-1),game(n,v,s,e-2)); return max(op1,op2); } int MaxValue(int n, vector v){ int res=game(n,v,0,n-1); return res; } ================================================ FILE: DSA Essentials Solutions/Dynamic Programming/Vacation.cpp ================================================ #include using namespace std; using ll = long long; using vi = vector; using vl = vector; using vvl = vector; using vs = vector; using mi = map; using ml = map; using umi = unordered_map; using uml = unordered_map; using pi = pair; using pl = pair; using ti = tuple; using tl = tuple; using vii = vector; using viii = vector; using vll = vector; using vlll = vector; #define mem(dp) memset(dp, -1, sizeof(dp)) #define aut(a, b) for (auto&(a) : (b)) #define out(x, v) for (auto&(x) : (v)) cout << x << " "; cout << '\n'; #define rep(i, n) for (ll (i) = 0; (i) < (n); ++(i) ) #define repp(i, n) for (ll (i) = 1; (i) <= (n); ++(i) ) #define all(v) v.begin(), v.end() #define fi get<0> #define se get<1> #define th get<2> #define F first #define S second #define mp make_pair #define mt make_tuple #define pb push_back int topDown(viii &v, int n, int i, int dp[][4], int prev) { if (i == n) return 0; if (dp[i][prev] != -1) return dp[i][prev]; int op1 = INT_MIN, op2 = INT_MIN, op3 = INT_MIN; if (prev != 1) op1 = fi(v[i]) + topDown(v, n, i + 1, dp, 1); if (prev != 2) op2 = se(v[i]) + topDown(v, n, i + 1, dp, 2); if (prev != 3) op3 = th(v[i]) + topDown(v, n, i + 1, dp, 3); return dp[i][prev] = max(op1, max(op2, op3)); } int vacation(vector a, vector b, vector c) { viii v; int n = a.size(); rep(i, n) { v.pb(mt(a[i], b[i], c[i])); } int dp[n][4]; mem(dp); return topDown(v, n, 0, dp, 0); } ================================================ FILE: DSA Essentials Solutions/Graphs/AllPathsFromSourceToTarget.cpp ================================================ #include using namespace std; void dfs(vector>& graph, vector>& result, vector path, int src, int dst) { path.push_back(src); if(src == dst) { result.push_back(path); return; } for(auto node : graph[src]) dfs(graph, result, path, node, dst); } vector> allPathsSourceTarget(vector>& graph) { vector> paths; vector path; int nodes = graph.size(); if(nodes == 0) return paths; dfs(graph, paths, path, 0, nodes - 1); return paths; } ================================================ FILE: DSA Essentials Solutions/Graphs/FindStarInGraph.cpp ================================================ #include using namespace std; int findCenter(vector>& v) { pair f={v[0][0],v[0][1]}; pair s={v[1][0],v[1][1]}; if(f.first==s.first){ return f.first; } else if(f. first==s.second){ return f.first; } else if(f.second==s.first){ return f.second; } else{ return f.second; } } ================================================ FILE: DSA Essentials Solutions/Graphs/KeysAndRooms.cpp ================================================ #include using namespace std; bool canVisitAllRooms(vector>& rooms) { unordered_map map; int n=rooms.size(); for(int i=0;i q; q.push(0); while(!q.empty()){ int k=q.size(); while(k--){ int a=q.front(); q.pop(); map[a]=true; for(int j=0;j using namespace std; vector intersection(vector& nums1, vector& nums2) { unordered_map map; vector result; for(int i=0;i 0) { result.push_back(nums2[i]); map[nums2[i]] = 0; } } sort(result.begin(), result.end()); return result; } ================================================ FILE: DSA Essentials Solutions/Hashing/KSumSubarray.cpp ================================================ #include using namespace std; int longestSubarrayKSum(vector arr,int k){ int n = arr.size(); unordered_map m; int pre = 0; int len = 0; for(int i=0;i using namespace std; int maxProduct(vector& nums) { priority_queue q; for(int i=0; i using namespace std; int minSetSize(vector& arr) { int n=arr.size(); priority_queue q; unordered_map mp; for(int i=0; in/2){ sum+=q.top(); q.pop(); cnt++; } return cnt; } ================================================ FILE: DSA Essentials Solutions/Heaps/RelativeRanks.cpp ================================================ #include using namespace std; vector findRelativeRanks(vector& score) { priority_queue> pq; for(int i=0; i vec(n); int cnt=0; while(!pq.empty()){ cnt++; if(cnt==1){ cout<<"hey"< using namespace std; vector kWeakestRows(vector>& mat, int k) { priority_queue , vector>, greater> > pq; //Min-heap for(int i=0;i x; while(k>0) { pair temp=pq.top(); x.push_back(temp.second); pq.pop(); k--; } return x; } ================================================ FILE: DSA Essentials Solutions/Linked List/AlternateMerge.cpp ================================================ //Expected Time Complexity: O(n) #include using namespace std; class node{ public: int data; node* next; node(int data){ this->data = data; next = NULL; } }; node* apend(node* root, int d){ if(root == NULL) return new node(d); node* temp = root; while(temp->next){ temp = temp->next; } temp->next = new node(d); return root; } node* alternateMerge(node * root1, node* root2){ //Complete this function node* root = NULL; if(!root1) return root2; if(!root2) return root1; while(root1 && root2){ root = apend(root, root1->data); root = apend(root, root2->data); root1 = root1->next; root2 = root2->next; } if(root1){ while(root1){ root = apend(root, root1->data); root1 = root1->next; } } if(root2){ while(root2){ root = apend(root, root2->data); root2 = root2->next; } } return root; } ================================================ FILE: DSA Essentials Solutions/Linked List/BubbleSortOnLinkedList.cpp ================================================ //Expected Time Complexity: O(n^2) #include using namespace std; class node { public: int data; node *next; node(int data) { this->data = data; this->next = NULL; } }; int len(node* head) { node* temp = head ; int i = 0 ; while(temp!=NULL) { i++; temp=temp->next ; } return i ; } node* bubble_sort_LinkedList_itr(node* head) { int n = len(head)-1; while(n--) { node* prev =NULL; node*cur = head; while(cur->next!=NULL) { if(cur->data >=cur->next->data) { if(prev==NULL) { //first node node* nxt = cur->next ; cur->next = nxt->next ; nxt->next = cur ; prev=nxt ; head = prev ; } else { node* nxt = cur->next ; prev->next = nxt ; cur->next = nxt->next ; nxt->next = cur ; prev = nxt ; } } else { prev = cur ; cur=cur->next ; } } } return head ; } ================================================ FILE: DSA Essentials Solutions/Linked List/DeleteTail.cpp ================================================ //Expected Time Complexity: O(n) #include using namespace std; class node{ public: int data; node* next; node(int data){ this->data = data; next = NULL; } }; node* deleteTail(node * head){ //Complete this function if (head == NULL) return NULL; if (head->next == NULL) { delete head; return NULL; } // Find the second last node node* second_last = head; while (second_last->next->next != NULL) second_last = second_last->next; // Delete last node delete (second_last->next); // Change next of second last second_last->next = NULL; return head; } ================================================ FILE: DSA Essentials Solutions/Linked List/KthLastElement.cpp ================================================ //Expected Time Complexity: O(n) #include using namespace std; class node{ public: int data; node* next; node(int data){ this->data = data; next = NULL; } }; int kthLastElement(node * head,int k){ //Complete this function to return kth last element node * fast = head; node * slow = head; int cnt = 0; while(cnt < k){ fast = fast->next; cnt++; } while(fast!=NULL){ slow = slow->next; fast = fast->next; } return slow->data; } ================================================ FILE: DSA Essentials Solutions/Queues/FirstNonRepeatingLetter.cpp ================================================ //Expected Time Complexity: O(n) #include using namespace std; const int MAX_CHAR = 26; vector firstnonrepeating(vector str) { queue q; vector v; int charCount[MAX_CHAR] = { 0 }; for (int i = 0; i 1) q.pop(); else { v.push_back(q.front()); break; } } if (q.empty()) v.push_back('0'); } return v; } ================================================ FILE: DSA Essentials Solutions/Queues/InterleaveTwoHalvesOfQueue.cpp ================================================ //Expected Time Complexity: O(n) #include using namespace std; queue interLeave(queue q){ int n=q.size(); queue q1, q2; for (int i=0;i<(n/2);i++) { q1.push(q.front()); q.pop(); //Expected Time Complexity: O(2^n) } for (int i=0;i<(n/2);i++) { q2.push(q.front()); q.pop(); } for (int i=0;i<(n/2);i++) { q.push(q1.front()); q1.pop(); q.push(q2.front()); q2.pop(); } return q; } ================================================ FILE: DSA Essentials Solutions/Queues/SortQueueWithConstantSpace.cpp ================================================ #include using namespace std; int minIndex(queue &q, int sortedIndex) { int min_index = -1; int min_val = INT_MAX; int n = q.size(); for (int i=0; i &q, int min_index) { int min_val; int n = q.size(); for (int i = 0; i < n; i++) { int curr = q.front(); q.pop(); if (i != min_index) q.push(curr); else min_val = curr; } q.push(min_val); } void sortQueue(queue &q) { for (int i = 1; i <= q.size(); i++) { int min_index = minIndex(q, q.size() - i); insertMinToRear(q, min_index); } } queue sortqueue(queue &q) { sortQueue(q); return q; } ================================================ FILE: DSA Essentials Solutions/Recursion/2DArrayMerge.cpp ================================================ Hint: Divide, sort row-wise, sort col-wise #include using namespace std; void merge_row(vector> &mat,int i, int cs, int cm, int ce){ vector sorted; int x=cs; int y=cm+1; //cout<> &mat,int j, int rs, int rm, int re){ vector sorted; int x=rs; int y=rm+1; while(x<=rm && y<=re){ if(mat[x][j]> &mat, int rs, int rm, int re,int cs, int cm, int ce){ //for sorting rows for(int i=rs; i<=re; i++){ merge_row(mat,i,cs,cm,ce); } //for sorting columns for(int j=cs; j<=ce; j++){ merge_col(mat,j,rs,rm,re); } return; } void merge_sort(int m, int n, vector> &mat, int rs, int re, int cs, int ce){ //cout<=re && cs>=ce){ return; } int rm=(rs+re)/2; int cm=(cs+ce)/2; // cout<> mergeSort(int m, int n, vector> v){ merge_sort(m,n,v,0,m-1,0,n-1); return v; } ================================================ FILE: DSA Essentials Solutions/Recursion/AllOccurences.cpp ================================================ //Expected Time Complexity: O(N) #include using namespace std; vector vec; void helper(int k, vector v, int i){ if(i==v.size()){ return; } if(v[i]==k){ vec.push_back(i); } helper(k,v,i+1); return; } vector findAllOccurences(int k, vector v){ vec.clear(); helper(k,v,0); return vec; } ================================================ FILE: DSA Essentials Solutions/Recursion/BinaryStrings.cpp ================================================ //Expected Time Complexity: O(2^n) #include using namespace std; vector v; void helper(string str,int n,int i){ if(i==n){ v.push_back(str); return; } string s1= str; s1.push_back('0'); helper(s1,n,i+1); if(i>0 && str[i-1]=='0'){ str.push_back('1'); helper(str,n,i+1); } else if(i==0){ str.push_back('1'); helper(str,n,i+1); } return; } vector binaryStrings(int n){ v.clear(); string str; helper(str,n,0); return v; } ================================================ FILE: DSA Essentials Solutions/Recursion/FriendsParty.cpp ================================================ //Expected Time Complexity: O(2^n) #include using namespace std; int help(int n) { if (n <= 0) return 0; if(n == 2 || n == 1) return n; return help(n - 1) + (n - 1) * help(n - 2); } int friendsPairing(int n){ return help(n); } ================================================ FILE: DSA Essentials Solutions/Recursion/PrintIncreasingNumbers.cpp ================================================ //Expected Time Complexity: O(n) #include using namespace std; void help(int i, int n, vector &v) { if(i > n) return; v.push_back(i); help(i+1, n, v); } vector increasingNumbers(int N) { vector v; help(1, N, v); return v; } ================================================ FILE: DSA Essentials Solutions/Recursion/TilingProblem.cpp ================================================ //Expected Time Complexity: O(2^n) #include using namespace std; int tiles(int n,int m){ if(n using namespace std; bool duplicateParentheses(string str){ stack Stack; for (char ch : str) { if (ch == ')') { char top = Stack.top(); Stack.pop(); int elementsInside = 0; while (top != '(') { elementsInside++; top = Stack.top(); Stack.pop(); } if(elementsInside < 1) { return true; } } else Stack.push(ch); } return false; } ================================================ FILE: DSA Essentials Solutions/Stacks/MaximumRectangularAreaInHistogram.cpp ================================================ //Expected Time Complexity: O(n) #include using namespace std; int getMaxArea(vector hist) { int n = hist.size(); stack s; int max_area = 0; int tp; int area_with_top; int i = 0; while (i < n) { if (s.empty() || hist[s.top()] <= hist[i]) s.push(i++); else { tp = s.top(); s.pop(); area_with_top = hist[tp] * (s.empty() ? i : i - s.top() - 1); if (max_area < area_with_top) max_area = area_with_top; } } while (s.empty() == false) { tp = s.top(); s.pop(); area_with_top = hist[tp] * (s.empty() ? i : i - s.top() - 1); if (max_area < area_with_top) max_area = area_with_top; } return max_area; } ================================================ FILE: DSA Essentials Solutions/Stacks/NextGreaterElement.cpp ================================================ #include using namespace std; vector nextGreaterElement(vector arr){ int n = arr.size(); vector arr1(n, 0); stack s; for (int i = n - 1; i >= 0; i--) { while (!s.empty() && s.top() <= arr[i]) s.pop(); if (s.empty()) arr1[i] = -1; else arr1[i] = s.top(); s.push(arr[i]); } return arr1; } ================================================ FILE: DSA Essentials Solutions/Stacks/ReverseANumberUsingStack.cpp ================================================ //Expected Time Complexity: O(n) #include using namespace std; int reverse(int n){ int number = n; stack st; while (number != 0) { st.push(number % 10); number = number / 10; } int rev = 0; int i = 1; while (!st.empty()) { rev = rev + (st.top() * i); st.pop(); i = i * 10; } return rev; } ================================================ FILE: DSA Essentials Solutions/Stacks/StockSpanProblem.cpp ================================================ //Expected Time Complexity: O(n) #include using namespace std; vector stockSpanner(vector &a){ stack s; int n = a.size(); s.push(0); vector arr(n, 1); for (int i = 1; i < n; i++) { while (!s.empty() and a[s.top()] <= a[i]) { s.pop(); } if (!s.empty()) { arr[i] = i - s.top(); } else arr[i] = i + 1; s.push(i); } return arr; } ================================================ FILE: DSA Essentials Solutions/Strings/ArePermutation.cpp ================================================ //Expected Time Complexity= O(N log N) //Hint: Permuatations are just different arrangements of same alphabets. Can you make the arrangement same? #include using namespace std; bool arePermutation(string str1, string str2) { // Get lenghts of both strings int n1 = str1.length(); int n2 = str2.length(); // If length of both strings is not same, // then they cannot be Permutation if (n1 != n2) return false; // Sort both strings sort(str1.begin(), str1.end()); sort(str2.begin(), str2.end()); // Compare sorted strings for (int i = 0; i < n1; i++) if (str1[i] != str2[i]) return false; return true; } ================================================ FILE: DSA Essentials Solutions/Strings/BinaryStringToNumber.cpp ================================================ Expected Time Complexity : O(N) #include #include using namespace std; // Function to convert binary to decimal int binaryToDecimal(string n) { string num = n; int dec_value = 0; // Initializing base value to 1, i.e 2^0 int base = 1; int len = num.length(); for (int i = len - 1; i >= 0; i--) { if (num[i] == '1') dec_value += base; base = base * 2; } return dec_value; } ================================================ FILE: DSA Essentials Solutions/Strings/CheckPalindrome.cpp ================================================ Expected Time Complexity : O(N) #include using namespace std; bool isPalindrome(string str) { // Start from leftmost and rightmost corners of str int l = 0; int h = str.length() - 1; // Keep comparing characters while they are same while (h > l) { if (str[l++] != str[h--]) { return false; } } return true; } ================================================ FILE: DSA Essentials Solutions/Strings/RemoveDuplicates.cpp ================================================ Expected Time Complexity : O(N) #include using namespace std; string removeDuplicate(string s){ // your code goes here set ss(s.begin(), s.end()); string str; for (auto x : ss) str.push_back(x); return str; } ================================================ FILE: DSA Essentials Solutions/Strings/StringCompression.cpp ================================================ Expected Time Complexity : O(N) #include using namespace std; int compress(vector& chars) { int count_=1; string ans; for(int i=0;i using namespace std; string vowel(string S){ // your code goes here string out; for(auto x : S){ if(x=='a' || x=='e' || x=='i' || x=='o' || x=='u') out.push_back(x); } return out; } ================================================ FILE: DSA Essentials Solutions/Trie/PrefixStrings.cpp ================================================ #include using namespace std; class node{ public: char ch; unordered_map next; bool isTerminal; node(char a){ ch=a; bool isTerminal=false; } }; class Trie{ public: node*root= new node('\0'); void insert(string str){ node*temp=root; for(int i=0; inext.count(str[i])==0){ temp->next[str[i]]=new node(str[i]); } temp=temp->next[str[i]]; } temp->isTerminal=true; return; } void dfs(node*temp, vector &v, string word ){ if(temp->isTerminal){ v.push_back(word); } if(temp->next.empty()){ return; } for(auto p:temp->next){ word.push_back(p.first); dfs(temp->next[p.first],v,word); word.pop_back(); } return; } vector find(string str){ vector v; node* temp=root; string word=""; for(int i=0; inext.count(str[i])==0){ return v; } word.push_back(str[i]); temp=temp->next[str[i]]; } if(temp->isTerminal){ v.push_back(word); } dfs(temp,v,word); sort(v.begin(),v.end()); return v; } }; vector findPrefixStrings(vector words, string prefix){ Trie t; for(auto s:words){ t.insert(s); } vector res=t.find(prefix); return res; } ================================================ FILE: DSA Essentials Solutions/Vectors/MakeZeroes.cpp ================================================ #include using namespace std; vector> makeZeroes(vector> arr){ // your code goes here vector r,c; int n = arr.size(), m = arr[0].size(); for(int i=0; i using namespace std; void rotate(vector>& matrix) { int n = matrix.size(); int a = 0; int b = n-1; while(a using namespace std; bool comp(pair a, pair b){ return a.second < b.second; } vector> sortFruits(vector> v, string S){ // your code goes here if(S=="name") sort(v.begin(), v.end()); else sort(v.begin(), v.end(), comp); return v; } ================================================ FILE: DSA Essentials Solutions/Vectors/SortingCabs.cpp ================================================ #include using namespace std; bool comp(pair a, pair b){ float x = sqrt((a.first*a.first) + (a.second*a.second)); float y = sqrt((b.first*b.first) + (b.second*b.second)); return x < y; } vector> sortCabs(vector> v){ // your code goes here sort(v.begin(), v.end(), comp); return v; }