├── .github └── config.yml ├── .vscode └── settings.json ├── Array └── ArrayADT.cpp ├── Binary-Search ├── Arranging-coins.cpp ├── Binary_search.cpp ├── Search-Insert-Position.cpp └── sqrt(n).js ├── CODE_OF_CONDUCT.md ├── DP ├── 0-1 Knapsack │ ├── recursion+memoization.cpp │ ├── recursion.cpp │ ├── space-optimization.cpp │ ├── space-optimization2.cpp │ └── tabulation.cpp ├── 3D DP │ └── memoization.cpp ├── Climbing Stairs │ ├── recursion+memoization.cpp │ ├── recursion.cpp │ ├── space-optimization.cpp │ └── tabulation.cpp ├── Coin Change │ ├── recursion+memoization.cpp │ ├── recursion.cpp │ └── tabulation.cpp ├── Combination Sum │ ├── recursion+memoization.cpp │ ├── recursion.cpp │ └── tabulation.cpp ├── Count derangements │ ├── recursion+memoization.cpp │ ├── recursion.cpp │ ├── space-optimization.cpp │ └── tabulation.cpp ├── Cut Into Segments │ ├── recursion+memoization.cpp │ ├── recursion.cpp │ └── tabulation.cpp ├── Fibonacci │ ├── recursion+memoization.cpp │ ├── recursion.cpp │ ├── space-optimization.cpp │ └── tabulation.cpp ├── Frog Jump │ └── solution.cpp ├── House Robber │ ├── recursion+memoization.cpp │ └── recursion.cpp ├── Longest Increasing Subsequence │ ├── DP_with_BinarySearch.cpp │ ├── recursion+memoization.cpp │ ├── recursion.cpp │ ├── space-optimization.cpp │ └── tabulation.cpp ├── Maximal Square │ ├── recursion+memoization.cpp │ └── recursion.cpp ├── Maximum sum of non-adjacent elements │ ├── recursion+memoization.cpp │ ├── recursion.cpp │ ├── space-optimization.cpp │ └── tabulation.cpp ├── Min Cost Climbing Stairs │ ├── recursion+memoization.cpp │ ├── recursion.cpp │ ├── space-optimization.cpp │ └── tabulation.cpp ├── Minimum Cost For Tickets │ ├── recursion+memoization.cpp │ ├── recursion.cpp │ └── tabulation.cpp ├── Minimum Path Sum Grid │ └── solution.cpp ├── Minimum Score Triangulation of Polygon │ ├── recursion+memoization.cpp │ ├── recursion.cpp │ └── tabulation.cpp ├── Minimum Sideway Jumps │ ├── recursion+memoization.cpp │ ├── recursion.cpp │ ├── spaceOptimization.cpp │ └── tabulation.cpp ├── Ninja’s Training │ └── solution.cpp ├── Painting Fence │ ├── recursion+memoization.cpp │ ├── recursion.cpp │ └── tabulation.cpp ├── Perfect Squares │ ├── recursion+memoization.cpp │ ├── recursion.cpp │ └── tabulation.cpp ├── Pizza With 3n Slices │ ├── recursion+memoization.cpp │ └── recursion.cpp ├── Reducing Dishes │ ├── recursion+memoization.cpp │ ├── recursion.cpp │ ├── space-optimization.cpp │ └── tabulation.cpp ├── Subset Sum Equal To K │ ├── memoization.cpp │ ├── recursion.cpp │ ├── space-optimization.cpp │ └── tabulation.cpp ├── Total Unique Paths │ └── solution.cpp ├── Triangle │ └── solution.cpp └── Unique Paths With Obstacles │ └── solution.cpp ├── Diamond Problem ├── problem.cpp └── solution.cpp ├── Dynamic Programming ├── 1D DP │ ├── Climbing_Stairs.cpp │ ├── Fibonacci_Number.cpp │ ├── Frog_Jump.cpp │ ├── House_Robber.cpp │ ├── House_Robber_II.cpp │ └── Minimal_Cost.cpp └── 2D 3D DP - DP ON GRIDS │ ├── Minimum_Falling_Path_Sum.cpp │ ├── Minimum_Falling_Path_Sum_II.cpp │ ├── Minimum_Path_Sum.cpp │ ├── Unique_Paths.cpp │ └── Unique_Paths_II.cpp ├── Graph ├── BFS.cpp ├── Bridges-In-A-Graph.cpp ├── Count-Strongly-Connected-Components-Kosaraju’sAlgorithm.cpp ├── Cycle-Detection-Undirected-graph.cpp ├── Cycle-Detection-directed-graph-Kahn's-Algo.cpp ├── Cycle-Detection-directed-graph.cpp ├── DFS_Iterative.cpp ├── DFS_Recursion.cpp ├── Disjoint_Set.cpp ├── Disjoint_set_by_size ├── Disjoint_set_by_size.cpp ├── Kruskal's-algorithm.cpp ├── Number-of-Distinct-islands.cpp ├── Shortest-path-unweighted-DAG.cpp ├── Shortest-path-unweighted-undirected-graph.cpp ├── bellmonFord-algo.cpp ├── cycle-in-starGraph.cpp ├── dijkstra.cpp ├── graph-adj-list.cpp ├── graph-implementation.cpp ├── prims.cpp ├── topological-sort-Kahn's-Algo.cpp └── topological-sort.cpp ├── Hashmap ├── Max-Frequency-Num.cpp └── map-stl.cpp ├── LICENSE ├── Linked-List ├── Circular-Singly-Linked-List.cpp ├── Convert_Binary_Number_Linked_List_To_Integer.cpp ├── Copy-List-with-Random-Pointer.cpp ├── Doubly-Linked-List.cpp ├── MergeKSortedLists.cpp ├── Merge_Nodes_in_Between_Zeros.cpp ├── PartitionList.cpp ├── RemoveDuplicatesFromUnsortedLL.cpp ├── Reverse-DLL.cpp ├── Reverse-LL.cpp ├── Reverse-in-group-of-K.cpp ├── Singly-Linked-List.cpp ├── XOR_Linked_List.cpp ├── addTwoNumbers-II.cpp ├── addTwoNumbers.cpp ├── deleteDuplicates.cpp ├── deleteDuplicates2.cpp ├── deleteParticularElement.cpp ├── detectCycle.cpp ├── getIntersectionNode.cpp ├── mergeSort_LL.cpp ├── mergeTwoLists.cpp ├── middle-of-LL.cpp ├── palindromeLL.cpp ├── reverseKGroup.cpp └── rotateRight.cpp ├── Mathematical Algorithms ├── Divisibility & Large Numbers │ ├── divisibilityBy3.cpp │ ├── divisibleBy11.cpp │ ├── divisibleBy13.cpp │ ├── divisibleBy4.cpp │ └── divisibleBy7.cpp ├── LCM & GCD │ ├── ExtendedEuclideanAlgorithm.cpp │ ├── gcdOfFloats.cpp │ ├── goodPair.cpp │ └── lcmOfArray.cpp └── Modular Arithmatic │ └── Find (a^b)%m where ‘b’ is very large │ └── solution.cpp ├── Queue ├── FirstNonRepeating.cpp ├── circular-queue.cpp ├── circularTour.cpp ├── doubly-ended-queue.cpp ├── input-restricted-queue.cpp ├── interLeaveQueue.cpp ├── k-queue-in-one-array.cpp ├── maxInSlidingWindow.cpp ├── output-restricted-queue.cpp ├── queue-stl.cpp ├── queueUsingStack.cpp ├── queue_Implementation_arr.cpp ├── reverse-queue.cpp └── reverseElementsinK.cpp ├── README.md ├── SECURITY.md ├── Sorting └── binary_insertion_sort.cpp ├── Stack ├── MaximalRectangle.cpp ├── N-Stack-in-OneArray.cpp ├── RedundantBrackets.cpp ├── Valid-Parentheses.cpp ├── celebrityProblem.cpp ├── deleteMiddle.cpp ├── largestRectangleArea.cpp ├── minAddToMakeValidBrackets.cpp ├── nextGreaterElement.cpp ├── pushAtBottom.cpp ├── reverseStack.cpp ├── sortStack.cpp ├── stack-implementation-LL.cpp ├── stack-implimentation-arr.cpp ├── stack-inCPP-STL.cpp └── two-stacks-one-arr.cpp ├── String └── ComputingLPS.cpp ├── Tree ├── BST │ ├── 2-SUM-BST.cpp │ ├── LCA-in-BST.cpp │ ├── MaximumSumBST-in-BinaryTree.cpp │ ├── balanceBST.cpp │ ├── bstFromPreorder.cpp │ ├── convertBST-to-GreaterTree.cpp │ ├── create-BST.cpp │ ├── deletion-in-BST.cpp │ ├── kthSmallest_BST.cpp │ ├── largestBST-in-Btree.cpp │ ├── mergeTwoBST.cpp │ ├── minValueInBST.cpp │ ├── search-In-BST.cpp │ ├── sortedArrayToBST.cpp │ ├── sortedListToBST.cpp │ └── validate_BST.cpp ├── Flatten-Binary-Tree-to-Linked-List.cpp ├── Heap │ ├── Check-Completeness-of-BinaryTree.cpp │ ├── Convert-BST-to-MinHeap.cpp │ ├── Kth_Largest_smallest_in_array.cpp │ ├── Median-in-stream.cpp │ ├── Merge-K-Sorted-Lists.cpp │ ├── Merge-K-SortedArrays.cpp │ ├── MinimumCost-of-ropes.cpp │ ├── PriorityQueue(Using STL).c │ ├── Smallest-Range-Covering-Elements-from-K-Lists.cpp │ ├── custom-conparator.cpp │ ├── getKthLargest.cpp │ ├── heapSort.cpp │ ├── heapify.cpp │ ├── implementation.cpp │ └── isBST-Heap.cpp ├── Invert-Binary-Tree.cpp ├── LowestCommonAncestor.cpp ├── Morris-Inorder-Traversal.cpp ├── No-Of-Leaf-Nodes.cpp ├── Segment Tree │ └── implementation.cpp ├── balancedTree.cpp ├── bottomView.cpp ├── boundaryTraversal.cpp ├── construct-TreeFrom-in_&_post.cpp ├── construct-TreeFrom-in_&_pre.cpp ├── countNodesIn-CBST.cpp ├── create-binaryTree.cpp ├── diagonalTraversal.cpp ├── diameterOfTree.cpp ├── findBottomLeftValue.cpp ├── getMaxSum-of-Non-adjoint-Nodes.cpp ├── goodNodes.cpp ├── isLeafSimilar.cpp ├── isSumTree.cpp ├── isSymmetric.cpp ├── kthAncestor.cpp ├── leftView.cpp ├── maximumHeight.cpp ├── merge-two-Btrees.cpp ├── minTimeToBurnTree.cpp ├── minimumHeight.cpp ├── pathSumTarget.cpp ├── removeLeafNodes-With-TargetVal.cpp ├── reverseLevelOrderTraversal.cpp ├── rightView.cpp ├── sameTree.cpp ├── sumOfLongRootToLeafPath.cpp ├── topView.cpp ├── treeTraversal.md ├── verticalOrderTraversal.cpp └── zigzagLevelOrder.cpp ├── Trie ├── Implement-phone-directory.cpp └── implementation.cpp ├── bit Manipulation ├── bitmask_flip_bit_index.cpp ├── bitmask_remove_last_set_bit.cpp ├── bitmask_set_index.cpp ├── bitmask_unset_index.cpp └── removing_OR_contribution.cpp └── lamda_function.cpp /.github/config.yml: -------------------------------------------------------------------------------- 1 | # Configuration for welcome - https://github.com/behaviorbot/welcome 2 | 3 | newIssueWelcomeComment: > 4 | Thanks for opening your first issue here! 💖 Be sure to follow the issue template! 5 | newPRWelcomeComment: | 6 | Thanks for opening this pull request! 💖 7 | Make sure you have read [contribution guidelines](https://github.com/SahilK-027/LeetCode/blob/main/CONTRIBUTING.md) and Follow the PR template! 8 | firstPRMergeComment: > 9 | Congrats on merging your first pull request! We are proud of you! 🎉🎉🎉 10 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "*.embeddedhtml": "html", 4 | "random": "cpp", 5 | "vector": "cpp", 6 | "iostream": "cpp", 7 | "ostream": "cpp" 8 | } 9 | } -------------------------------------------------------------------------------- /Binary-Search/Arranging-coins.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * @file Arranging-coins.cpp 3 | * @brief 4 | * You have n coins and you want to build a staircase with these coins. 5 | * The staircase consists of k rows where the ith row has exactly i coins. 6 | * The last row of the staircase may be incomplete. 7 | * Given the integer n, return the number of complete rows of the staircase you will build. 8 | */ 9 | 10 | /** 11 | * @brief I/O EXPLANATION 12 | * Input: n = 5 13 | * Output: 2 14 | * Explanation: Because the 3rd row is incomplete, we return 2. 15 | */ 16 | 17 | // Using BS 18 | int arrangeCoins(int n) 19 | { 20 | int s = 1; 21 | int e = n; 22 | double m = s + (e - s) / 2; 23 | while (s <= e) 24 | { 25 | long long coins_used = m / 2 * (m + 1); 26 | if (coins_used == n) 27 | { 28 | return (int)m; 29 | } 30 | else if (n < coins_used) 31 | { 32 | e = m - 1; 33 | } 34 | else 35 | { 36 | s = m + 1; 37 | } 38 | m = s + (e - s) / 2; 39 | } 40 | return e; 41 | } -------------------------------------------------------------------------------- /Binary-Search/Binary_search.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int Binary_search(int *arr, int n, int key){ 4 | int s = 0; 5 | int e = n - 1; 6 | int m = s + (e - s) / 2; 7 | while (s <= e){ 8 | if(arr[m] == key) return m; 9 | else if(arr[m] > key) e = m -1; 10 | else s = m + 1; 11 | m = s + (e - s) / 2; 12 | } 13 | return -1; 14 | } 15 | int main(){ 16 | int arr[5] = {1, 2, 3, 4, 5}; 17 | cout << Binary_search(arr, 5, 10); 18 | return 0; 19 | } -------------------------------------------------------------------------------- /Binary-Search/Search-Insert-Position.cpp: -------------------------------------------------------------------------------- 1 | int searchInsert(vector &arr, int t) 2 | { 3 | int s = 0; 4 | int e = arr.size() - 1; 5 | int m = s + (e - s) / 2; 6 | int ans = 0; 7 | while (s <= e) 8 | { 9 | if (arr[m] == t) 10 | { 11 | return m; 12 | } 13 | else if (arr[m] < t) 14 | { 15 | s = m + 1; 16 | } 17 | else 18 | { 19 | e = m - 1; 20 | } 21 | m = s + (e - s) / 2; 22 | } 23 | return s; 24 | } -------------------------------------------------------------------------------- /Binary-Search/sqrt(n).js: -------------------------------------------------------------------------------- 1 | var mySqrt = function(x) { 2 | let s = 0; 3 | let e = Math.ceil(x/2); 4 | let m = parseInt(s + (e-s)/2); 5 | let possible_ans = -1; 6 | while(s <= e){ 7 | if(m * m == x) return m; 8 | else if(m * m < x){ 9 | possible_ans = m; 10 | s = m + 1; 11 | } 12 | else{ 13 | e = m - 1; 14 | } 15 | m = parseInt(s + (e-s)/2); 16 | } 17 | return possible_ans; 18 | }; -------------------------------------------------------------------------------- /DP/0-1 Knapsack/recursion+memoization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int solveMemoization(vector& weight, vector& value, int i, int n, int capacity, vector>& dp){ 3 | // Base caase we are standing at last element 4 | if(i == n-1){ 5 | // if we haave enough capacity 6 | if(weight[i] <= capacity){ 7 | return value[i]; 8 | } 9 | else{ 10 | return 0; 11 | } 12 | } 13 | 14 | // If already calculated answer then return 15 | if(dp[i][capacity] != -1) return dp[i][capacity]; 16 | // Inclusion exclusion call 17 | int include = 0, exclude = 0; 18 | if(weight[i] <= capacity){ 19 | include = value[i] + solveMemoization(weight, value, i+1, n, capacity - weight[i], dp); 20 | } 21 | exclude = 0 + solveMemoization(weight, value, i+1, n, capacity, dp); 22 | 23 | // Step 2: Store answer at changed parameters in DP 24 | return dp[i][capacity] = max(include, exclude); 25 | } 26 | int knapsack(vector weight, vector value, int n, int maxWeight) 27 | { 28 | // Step 1: Create DP 29 | vector> dp(n, vector(maxWeight+1, -1)); 30 | return solveMemoization(weight, value, 0, n, maxWeight, dp); 31 | } 32 | -------------------------------------------------------------------------------- /DP/0-1 Knapsack/recursion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int solve(vector& weight, vector& value, int i, int n, int capacity){ 3 | // Base caase we are standing at last element 4 | if(i == n-1){ 5 | // if we have enough capacity to include last element 6 | if(weight[i] <= capacity){ 7 | return value[i]; 8 | } 9 | else{ 10 | return 0; 11 | } 12 | } 13 | 14 | // Inclusion exclusion calls 15 | int include = 0, exclude = 0; 16 | if(weight[i] <= capacity){ 17 | include = value[i] + solve(weight, value, i+1, n, capacity - weight[i]); 18 | } 19 | exclude = 0 + solve(weight, value, i+1, n, capacity); 20 | 21 | return max(include, exclude); 22 | } 23 | int knapsack(vector weight, vector value, int n, int maxWeight) 24 | { 25 | return solve(weight, value, 0, n, maxWeight); 26 | } 27 | -------------------------------------------------------------------------------- /DP/0-1 Knapsack/space-optimization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int SO(vector& weight, vector& value, int n, int capacity){ 3 | // Step 1: Create Table 4 | vector prev(capacity+1, 0); 5 | vector curr(capacity+1, 0); 6 | 7 | // Step 2: Analyze the base cases to fill table 8 | for(int w = weight[0]; w <= capacity; w++){ 9 | if(weight[0] <= capacity){ 10 | prev[w] = value[0]; 11 | } 12 | else{ 13 | prev[w] = 0; 14 | } 15 | } 16 | 17 | for(int row = 1; row < n; row++){ 18 | for(int c = 0; c <= capacity; c++){ 19 | int include = 0, exclude = 0; 20 | if(weight[row] <= c){ 21 | include = value[row] + prev[c - weight[row]]; 22 | } 23 | exclude = 0 + prev[c]; 24 | 25 | curr[c] = max(include, exclude); 26 | } 27 | prev = curr; 28 | } 29 | return prev[capacity]; 30 | } 31 | int knapsack(vector weight, vector value, int n, int capacity) 32 | { 33 | return SO(weight, value, n, capacity); 34 | } 35 | -------------------------------------------------------------------------------- /DP/0-1 Knapsack/space-optimization2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int SO(vector& weight, vector& value, int n, int capacity){ 3 | // Step 1: Create Table 4 | vector curr(capacity+1, 0); 5 | 6 | // Step 2: Analyze the base cases to fill table 7 | for(int w = weight[0]; w <= capacity; w++){ 8 | if(weight[0] <= capacity){ 9 | curr[w] = value[0]; 10 | } 11 | else{ 12 | curr[w] = 0; 13 | } 14 | } 15 | 16 | for(int row = 1; row < n; row++){ 17 | // Go right to left 18 | for(int c = capacity; c >= 0; c--){ 19 | int include = 0, exclude = 0; 20 | if(weight[row] <= c){ 21 | include = value[row] + curr[c - weight[row]]; 22 | } 23 | exclude = 0 + curr[c]; 24 | 25 | curr[c] = max(include, exclude); 26 | } 27 | } 28 | return curr[capacity]; 29 | } 30 | int knapsack(vector weight, vector value, int n, int capacity) 31 | { 32 | return SO(weight, value, n, capacity); 33 | } 34 | -------------------------------------------------------------------------------- /DP/0-1 Knapsack/tabulation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int solveTab(vector& weight, vector& value, int n, int capacity){ 3 | // Step 1: Create Table 4 | vector> dp(n, vector(capacity+1, 0)); 5 | 6 | // Step 2: Analyze the base cases to fill table 7 | for(int w = weight[0]; w <= capacity; w++){ 8 | if(weight[0] <= capacity){ 9 | dp[0][w] = value[0]; 10 | } 11 | else{ 12 | dp[0][w] = 0; 13 | } 14 | } 15 | 16 | for(int row = 1; row < n; row++){ 17 | for(int c = 0; c <= capacity; c++){ 18 | int include = 0, exclude = 0; 19 | if(weight[row] <= c){ 20 | include = value[row] + dp[row-1][c - weight[row]]; 21 | } 22 | exclude = 0 + dp[row-1][c]; 23 | 24 | dp[row][c] = max(include, exclude); 25 | } 26 | } 27 | return dp[n-1][capacity]; 28 | } 29 | int knapsack(vector weight, vector value, int n, int capacity) 30 | { 31 | return solveTab(weight, value, n, capacity); 32 | } 33 | -------------------------------------------------------------------------------- /DP/3D DP/memoization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int solve(int i, int j1, int j2, vector> &a, vector&D, vector>>& dp){ 3 | // Bace case 4 | // Checking out of bound 5 | if(j1 < 0 || j2 < 0 || j1 >= a[0].size() || j2 >= a[0].size()) 6 | return -1e8; 7 | if(i == a.size() - 1){ 8 | if(j1 == j2) 9 | return a[i][j1]; 10 | else 11 | return a[i][j1] + a[i][j2]; 12 | } 13 | if(dp[i][j1][j2] != -1) return dp[i][j1][j2]; 14 | int maxi = INT_MIN; 15 | for(auto di: D){ 16 | for(auto dj: D){ 17 | if(j1 == j2) 18 | maxi = max(maxi, a[i][j1] + solve(i+1, j1 + di , j2 + dj, a, D, dp)); 19 | else 20 | maxi = max(maxi, a[i][j1] + a[i][j2] + 21 | solve(i+1, j1+di, j2 + dj, a, D, dp)); 22 | } 23 | } 24 | return dp[i][j1][j2] = maxi; 25 | } 26 | int maximumChocolates(int r, int c, vector> &grid) { 27 | vectordelta = {-1,0,1}; 28 | vector>>dp(r, vector>(c, vector(c, -1))); 29 | return solve(0, 0, c-1, grid, delta, dp); 30 | } 31 | -------------------------------------------------------------------------------- /DP/Climbing Stairs/recursion+memoization.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solveMemoization(int n, vector& dp) 4 | { 5 | // if we reached the ground 6 | if( n == 0 ){ 7 | return 1; 8 | } 9 | // If the path doesn't take us to ground 10 | if( n < 0 ){ 11 | return 0; 12 | } 13 | if(dp[n] != -1) return dp[n]; 14 | // Return the path which we get by climbing 15 | return dp[n] = solveMemoization(n-1, dp) + solveMemoization(n - 2, dp); 16 | } 17 | 18 | public: 19 | int climbStairs(int n) { 20 | vectordp(n+1, -1); 21 | return solveMemoization(n, dp); 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /DP/Climbing Stairs/recursion.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int climbStairs(int n) { 4 | // if we reached the ground 5 | if( n == 0 ){ 6 | return 1; 7 | } 8 | // If the path doesn't take us to ground 9 | if( n < 0 ){ 10 | return 0; 11 | } 12 | 13 | // Return the path which we get by climbing 14 | return climbStairs(n-1) + climbStairs(n - 2); 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /DP/Climbing Stairs/space-optimization.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solveSO(int n) 4 | { 5 | int prev2 = 1; 6 | int prev1 = 1; 7 | int curr = 0; 8 | for(int i = 2; i <= n; i++){ 9 | curr = prev2+prev1; 10 | prev2 = prev1; 11 | prev1 = curr; 12 | } 13 | return prev1; 14 | } 15 | 16 | public: 17 | int climbStairs(int n) { 18 | return solveSO(n); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /DP/Climbing Stairs/tabulation.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solveTab(int n) 4 | { 5 | vector dp(n+1); 6 | dp[0] = 1; 7 | dp[1] = 1; 8 | for(int i = 2; i <= n; i++){ 9 | dp[i] = dp[i-1] + dp[i-2]; 10 | } 11 | return dp[n]; 12 | } 13 | 14 | public: 15 | int climbStairs(int n) { 16 | return solveTab(n); 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /DP/Coin Change/recursion+memoization.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solveMemoization(vector& coins, int amount, vector& dp){ 4 | if(amount == 0) return 0; 5 | if(amount < 0) return INT_MAX; 6 | 7 | // Step 3: If answer is already calculated return answer 8 | if(dp[amount] != -1) return dp[amount]; 9 | 10 | int mini = INT_MAX; 11 | for(int i= 0 ; i < coins.size(); i++){ 12 | int ans = solveMemoization(coins, amount - coins[i], dp); 13 | if(ans != INT_MAX){ 14 | mini = min(mini, ans+1); 15 | } 16 | } 17 | 18 | // Step 2: Store answer in DP 19 | return dp[amount] = mini; 20 | } 21 | public: 22 | int coinChange(vector& coins, int amount) { 23 | // Step 1: Craete and pass DP 24 | vector dp(amount+1, -1); 25 | int ans = solveMemoization(coins, amount, dp); 26 | if(ans == INT_MAX) return -1; 27 | return ans; 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /DP/Coin Change/recursion.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solve(vector& coins, int amount){ 4 | if(amount == 0) return 0; 5 | if(amount < 0) return INT_MAX; 6 | 7 | int mini = INT_MAX; 8 | for(int i= 0 ; i < coins.size(); i++){ 9 | int ans = solve(coins, amount - coins[i]); 10 | if(ans != INT_MAX){ 11 | mini = min(mini, ans+1); 12 | } 13 | } 14 | 15 | return mini; 16 | } 17 | public: 18 | int coinChange(vector& coins, int amount) { 19 | int ans = solve(coins, amount); 20 | if(ans == INT_MAX) return -1; 21 | return ans; 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /DP/Coin Change/tabulation.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solveTab(vector& coins, int amount){ 4 | vectordp(amount+1 ,INT_MAX); 5 | dp[0] = 0; 6 | 7 | for(int i = 1 ; i <= amount; i++){ 8 | // Utilize all coins for current amount 9 | for(auto c: coins){ 10 | // Checking for valid index 11 | if(i - c >= 0 && dp[i - c] != INT_MAX){ 12 | dp[i] = min(dp[i], 1 + dp[i - c]); 13 | } 14 | } 15 | } 16 | if(dp[amount] == INT_MAX){ 17 | return -1; 18 | } 19 | else{ 20 | return dp[amount]; 21 | } 22 | } 23 | public: 24 | int coinChange(vector& coins, int amount) { 25 | if(amount == 0){ 26 | return 0; 27 | } 28 | return solveTab(coins, amount); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /DP/Combination Sum/recursion+memoization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int solveMemoization(vector &arr, int t, vector& dp){ 3 | if(t == 0) return 1; 4 | if(t < 0) return 0; 5 | if(dp[t] != -1) return dp[t]; 6 | 7 | int ans = 0; 8 | for(int i = 0 ; i < arr.size(); i++){ 9 | ans += solveMemoization(arr, t - arr[i], dp); 10 | } 11 | return dp[t] = ans; 12 | } 13 | int findWays(vector &arr, int t) 14 | { 15 | vector dp(t+1, -1); 16 | return solveMemoization(arr, t, dp); 17 | } 18 | -------------------------------------------------------------------------------- /DP/Combination Sum/recursion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int solve(vector &arr, int t){ 3 | if(t == 0) return 1; 4 | if(t < 0) return 0; 5 | 6 | int ans = 0; 7 | for(int i = 0 ; i < arr.size(); i++){ 8 | ans += solve(arr, t - arr[i]); 9 | } 10 | return ans; 11 | } 12 | int findWays(vector &arr, int t) 13 | { 14 | return solve(arr, t); 15 | } 16 | -------------------------------------------------------------------------------- /DP/Combination Sum/tabulation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int solveTab(vector &arr, int t){ 3 | vector dp(t+1, 0); 4 | dp[0] = 1; 5 | 6 | // Loop to fill table 7 | for(int i = 1; i <= t; i++){ 8 | // Loop used in recursive code 9 | for(int j = 0 ; j < arr.size(); j++){ 10 | if(i - arr[j] >= 0){ 11 | dp[i] += dp[i - arr[j]]; 12 | } 13 | } 14 | } 15 | 16 | return dp[t]; 17 | } 18 | int findWays(vector &arr, int t) 19 | { 20 | return solveTab(arr, t); 21 | } 22 | -------------------------------------------------------------------------------- /DP/Count derangements/recursion+memoization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define M 1000000007 3 | #define lli long long int 4 | 5 | lli solveMemoization(int n, vector& dp){ 6 | if( n < 2 ) return 0; 7 | if( n == 2) return 1; 8 | if(dp[n] != -1) return dp[n]; 9 | return 10 | dp[n] = ((n-1) % M * (solveMemoization(n-1, dp) + solveMemoization(n-2, dp)))%M; 11 | } 12 | lli countDerangements(int n) { 13 | vector dp(n+1, -1); 14 | return solveMemoization(n, dp); 15 | } 16 | -------------------------------------------------------------------------------- /DP/Count derangements/recursion.cpp: -------------------------------------------------------------------------------- 1 | #define M 1000000007 2 | long long int countDerangements(int n) { 3 | // Base case 4 | if( n < 2 ) return 0; 5 | if( n == 2) return 1; 6 | // Recursive call 7 | return ((n-1) % M * (countDerangements(n-1) + countDerangements(n-2)))%M; 8 | } 9 | -------------------------------------------------------------------------------- /DP/Count derangements/space-optimization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define M 1000000007 3 | #define lli long long int 4 | 5 | lli SO(int n){ 6 | lli prev2 = 0; 7 | lli prev1 = 1; 8 | 9 | for(int i = 3; i <= n; i++){ 10 | lli curr = ((i - 1) % M * (prev1 + prev2)) % M; 11 | prev2 = prev1; 12 | prev1 = curr; 13 | } 14 | return prev1; 15 | } 16 | lli countDerangements(int n) { 17 | return SO(n); 18 | } 19 | -------------------------------------------------------------------------------- /DP/Count derangements/tabulation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define M 1000000007 3 | #define lli long long int 4 | 5 | lli tabulation(int n){ 6 | vector dp(n+1, -1); 7 | dp[0] = 0; 8 | dp[1] = 0; 9 | dp[2] = 1; 10 | 11 | for(int i = 3; i <= n; i++){ 12 | dp[i] = ((i - 1) % M * (dp[i-1] + dp[i-2])) % M; 13 | } 14 | return dp[n]; 15 | } 16 | lli countDerangements(int n) { 17 | return tabulation(n); 18 | } 19 | -------------------------------------------------------------------------------- /DP/Cut Into Segments/recursion+memoization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int solveMemoization(int n, int x, int y, int z, vector& dp){ 3 | // Base case 4 | if(n == 0) return 0; 5 | if(n < 0) return INT_MIN; 6 | if(dp[n] != -1) return dp[n]; 7 | // +1 to include current segement 8 | // take x length segment 9 | int ans1 = solveMemoization(n-x, x, y, z, dp) + 1; 10 | // take y length segment 11 | int ans2 = solveMemoization(n-y, x, y, z, dp) + 1; 12 | // take z length segment 13 | int ans3 = solveMemoization(n-z, x, y, z, dp) + 1; 14 | 15 | int ans = max(ans1, max(ans2, ans3)); 16 | 17 | return dp[n] = ans; 18 | } 19 | int cutSegments(int n, int x, int y, int z) { 20 | vector dp(n+1, -1); 21 | return solveMemoization(n, x, y, z, dp) < 0 ? 0 : solveMemoization(n, x, y, z, dp); 22 | } 23 | -------------------------------------------------------------------------------- /DP/Cut Into Segments/recursion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int solve(int n, int x, int y, int z){ 3 | // Base case 4 | if(n == 0) return 0; 5 | if(n < 0) return INT_MIN; 6 | // +1 to include current segement 7 | // take x length segment 8 | int ans1 = solve(n-x, x, y, z) + 1; 9 | // take y length segment 10 | int ans2 = solve(n-y, x, y, z) + 1; 11 | // take z length segment 12 | int ans3 = solve(n-z, x, y, z) + 1; 13 | 14 | int ans = max(ans1, max(ans2, ans3)); 15 | 16 | return ans; 17 | } 18 | int cutSegments(int n, int x, int y, int z) { 19 | return solve(n, x, y, z) < 0 ? 0 : solve(n, x, y, z); 20 | } 21 | -------------------------------------------------------------------------------- /DP/Cut Into Segments/tabulation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int solveTab(int n, int x, int y, int z){ 3 | vector dp(n+1, INT_MIN); 4 | dp[0] = 0; 5 | 6 | for(int i = 1; i <= n ; i++){ 7 | if( i - x >= 0) 8 | dp[i] = max(dp[i], dp[i-x] + 1); 9 | if( i - y >= 0) 10 | dp[i] = max(dp[i], dp[i-y] + 1); 11 | if( i - z >= 0) 12 | dp[i] = max(dp[i], dp[i-z] + 1); 13 | } 14 | return dp[n]; 15 | } 16 | int cutSegments(int n, int x, int y, int z) { 17 | 18 | return solveTab(n, x, y, z) < 0 ? 0 : solveTab(n, x, y, z); 19 | } 20 | -------------------------------------------------------------------------------- /DP/Fibonacci/recursion+memoization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | // TOP - DOWN DP 4 | // Steps in MEMOIZATION 5 | // STEP 1: Create DP array just before function call + pass in fuction call 6 | // STEP 2: Store answer in DP array 7 | // STEP 3: Just after base case check if answer is already there in DP array if yes return ans 8 | int fib_memo(int n, vector &dp) 9 | { 10 | if (n < 2) 11 | return n; 12 | // Step 3: 13 | if (dp[n] != -1) 14 | { 15 | return dp[n]; 16 | } 17 | int ans = fib_memo(n - 1, dp) + fib_memo(n - 2, dp); 18 | // Step 2 19 | dp[n] = ans; 20 | return ans; 21 | } 22 | int main() 23 | { 24 | int n = 7; 25 | // Step 1 26 | vector dp(n + 1, -1); 27 | 28 | // Fib with memoization 29 | cout << fib_memo(n, dp) << endl; 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /DP/Fibonacci/recursion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // Recusrive 5 | int fibo(int n){ 6 | if(n < 2) return n; 7 | return fibo(n-1) + fibo(n-2); 8 | } 9 | int main() 10 | { 11 | int n = 7; 12 | // Recursive 13 | cout << fibo(n) << endl; 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /DP/Fibonacci/space-optimization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | // SPACE OPTIMIZATION 4 | int fib_SO(int n) 5 | { 6 | if(n < 2){ 7 | return n; 8 | } 9 | int prev1 = 1; 10 | int prev2 = 0; 11 | int curr; 12 | for(int i = 2 ; i <= n; i++) 13 | { 14 | curr = prev1 + prev2; 15 | prev2 = prev1; 16 | prev1 = curr; 17 | } 18 | return curr; 19 | } 20 | int main() 21 | { 22 | int n = 7; 23 | // Space optimization 24 | cout << fib_SO(n) << endl; 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /DP/Fibonacci/tabulation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | // BOTTOM - UP DP 4 | // Steps in Tabulation 5 | // STEP 1: Create DP array in fuction itself 6 | // STEP 2: Analyze base cases of recursive function and then modify DP array accordingly 7 | // STEP 3: for loop + rec logic 8 | int fib_tab(int n) 9 | { 10 | vector dp(n+1); 11 | dp[0] = 0; 12 | dp[1] = 1; 13 | for(int i = 2 ; i <= n; i++) 14 | { 15 | dp[i] = dp[i-1] + dp[i-2]; 16 | } 17 | return dp[n]; 18 | } 19 | int main() 20 | { 21 | int n = 7; 22 | // Bottom up - tabularization 23 | cout << fib_tab(n) << endl; 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /DP/Frog Jump/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int solveMem(int idx, vector &h, vector &dp){ 3 | if(idx == 0) return 0; 4 | if(dp[idx] != -1) return dp[idx]; 5 | int jump1 = solveMem(idx - 1, h, dp) + abs(h[idx] - h[idx-1]); 6 | int jump2 = INT_MAX; 7 | if(idx > 1){ 8 | jump2 = solveMem(idx - 2, h, dp) + abs(h[idx] - h[idx-2]); 9 | } 10 | return dp[idx] = min(jump1, jump2); 11 | } 12 | int solveTab(int n, vector &h){ 13 | vectordp(n+1, 0); 14 | dp[0] = 0; 15 | for(int i = 1; i <= n; i++){ 16 | int jump1 = dp[i - 1] + abs(h[i] - h[i-1]); 17 | int jump2 = INT_MAX; 18 | if(i > 1){ 19 | jump2 = dp[i - 2] + abs(h[i] - h[i-2]); 20 | } 21 | dp[i] = min(jump1, jump2); 22 | } 23 | return dp[n]; 24 | } 25 | int SO(int n, vector &h){ 26 | // vectordp(n+1, 0); 27 | // dp[0] = 0; 28 | int prev1 = 0; 29 | int prev2 = 0; 30 | for(int i = 1; i <= n; i++){ 31 | // int jump1 = dp[i - 1] + abs(h[i] - h[i-1]); 32 | int jump1 = prev1 + abs(h[i] - h[i-1]); 33 | 34 | int jump2 = INT_MAX; 35 | if(i > 1){ 36 | // jump2 = dp[i - 2] + abs(h[i] - h[i-2]); 37 | jump2 = prev2 + abs(h[i] - h[i-2]); 38 | 39 | } 40 | // dp[i] = min(jump1, jump2); 41 | int curr = min(jump1, jump2); 42 | prev2 = prev1; 43 | prev1 = curr; 44 | } 45 | return prev1; 46 | } 47 | int frogJump(int n, vector &heights) 48 | { 49 | vectordp(n, -1); 50 | return SO(n-1, heights); 51 | return solveTab(n-1, heights); 52 | return solveMem(n-1, heights, dp); 53 | } 54 | -------------------------------------------------------------------------------- /DP/House Robber/recursion+memoization.cpp: -------------------------------------------------------------------------------- 1 | // Recursive solution + DP 2 | class Solution { 3 | private: 4 | int solveMemoization(vector& nums, int s, int e, vector& dp){ 5 | // Base case 6 | if(s > e){ 7 | return 0; 8 | } 9 | if(dp[s] != -1){ 10 | return dp[s]; 11 | } 12 | // Include current house 13 | int include = nums[s] + solveMemoization(nums, s + 2, e, dp); 14 | // Exclude current house 15 | int exclude = 0 + solveMemoization(nums, s + 1, e, dp); 16 | // Return whichever answer will be maximum 17 | return dp[s] = max(include, exclude); 18 | } 19 | public: 20 | int rob(vector& nums) { 21 | if (nums.size() == 0) return 0; 22 | if (nums.size() == 1) return nums[0]; 23 | if (nums.size() == 2) return max(nums[0], nums[1]); 24 | int s = 0; 25 | int e = nums.size()-1; 26 | // Ans 1 will be for house 1 to second last house as last house will be adjacent house to house 1 in circle 27 | vector dp1(nums.size(), -1); 28 | int ans_1 = solveMemoization(nums, s, e-1, dp1); 29 | // Ans 2 will be for house 2 to the last house. 30 | vector dp2(nums.size(), -1); 31 | int ans_2 = solveMemoization(nums, s+1, e, dp2); 32 | // Finally return maximum of answers 33 | return max(ans_1, ans_2); 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /DP/House Robber/recursion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define ll long long 3 | ll solve(vector& arr, int i, int n){ 4 | if(i > n){ 5 | return 0; 6 | } 7 | ll include = solve(arr, i+2, n) + arr[i]; 8 | ll exclude = solve(arr, i+1, n) + 0; 9 | 10 | return max(include, exclude); 11 | } 12 | ll int houseRobber(vector& arr) 13 | { 14 | if(arr.size() == 1) return arr[0]; 15 | int e = arr.size()-1; 16 | ll ans = max(solve(arr, 0, e-1), solve(arr, 1, e)); 17 | return ans; 18 | } 19 | -------------------------------------------------------------------------------- /DP/Longest Increasing Subsequence/DP_with_BinarySearch.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int DP_with_BS(vector& nums){ 4 | int n = nums.size(); 5 | if(n == 0) return 0; 6 | vector ans; 7 | 8 | ans.push_back(nums[0]); 9 | 10 | for(int i = 1; i < n; i++){ 11 | if(nums[i] > ans.back()){ 12 | ans.push_back(nums[i]); 13 | } 14 | else{ 15 | // Find index of just greater element 16 | int index = lower_bound(ans.begin(), ans.end(), nums[i]) - ans.begin(); 17 | ans[index] = nums[i]; 18 | } 19 | } 20 | 21 | return ans.size(); 22 | } 23 | public: 24 | int lengthOfLIS(vector& nums) { 25 | if(nums.size() == 1) return 1; 26 | return DP_with_BS(nums); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /DP/Longest Increasing Subsequence/recursion+memoization.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solveMemoization(vector& nums, int prev, int curr, vector>& dp){ 4 | if(curr >= nums.size()){ 5 | return 0; 6 | } 7 | if(dp[curr][prev+1] != -1) return dp[curr][prev+1]; 8 | 9 | // Include 10 | int include = INT_MIN; 11 | if(prev == -1 || nums[curr] > nums[prev]){ 12 | include = 1 + solveMemoization(nums, curr, curr+1, dp); 13 | } 14 | // Exclude 15 | int exclude = 0 + solveMemoization(nums, prev, curr+1, dp); 16 | 17 | // Prev can be -1 as well so make prev + 1 18 | return dp[curr][prev+1] = max(include, exclude); 19 | } 20 | public: 21 | int lengthOfLIS(vector& nums) { 22 | if(nums.size() == 1) return 1; 23 | int curr = 0; 24 | int prev = -1; 25 | vector>dp(nums.size()+1, vector(nums.size() + 1, -1)); 26 | return solveMemoization(nums, prev, curr, dp); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /DP/Longest Increasing Subsequence/space-optimization.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int SO(vector& nums){ 4 | int n = nums.size(); 5 | vector current(n+1, 0); 6 | vector next(n+1, 0); 7 | 8 | for(int curr = n-1 ; curr >= 0; curr--){ 9 | for(int prev = curr-1; prev >= -1; prev--){ 10 | // Include 11 | int include = 0; 12 | if(prev == -1 || nums[curr] > nums[prev]){ 13 | include = 1 + next[curr+1]; 14 | } 15 | // Exclude 16 | int exclude = 0 + next[prev+1]; 17 | 18 | // Prev can be -1 as well so make prev + 1 19 | current[prev+1] = max(include, exclude); 20 | } 21 | next = current; 22 | } 23 | return next[0]; 24 | } 25 | public: 26 | int lengthOfLIS(vector& nums) { 27 | if(nums.size() == 1) return 1; 28 | return SO(nums); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /DP/Longest Increasing Subsequence/tabulation.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int Tabulation(vector& nums){ 4 | int n = nums.size(); 5 | vector>dp(nums.size()+1, vector(nums.size() + 1, 0)); 6 | 7 | for(int curr = n-1 ; curr >= 0; curr--){ 8 | for(int prev = curr-1; prev >= -1; prev--){ 9 | // Include 10 | int include = 0; 11 | if(prev == -1 || nums[curr] > nums[prev]){ 12 | include = 1 + dp[curr + 1][curr+1]; 13 | } 14 | // Exclude 15 | int exclude = 0 + dp[curr+1][prev+1]; 16 | 17 | // Prev can be -1 as well so make prev + 1 18 | dp[curr][prev+1] = max(include, exclude); 19 | } 20 | } 21 | return dp[0][0]; 22 | } 23 | public: 24 | int lengthOfLIS(vector& nums) { 25 | if(nums.size() == 1) return 1; 26 | return Tabulation(nums); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /DP/Maximal Square/recursion+memoization.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solveMemoization(vector>& matrix, int i, int j, int &maxi, vector>& dp){ 4 | // Base case 5 | if(i >= matrix.size() || j >= matrix[0].size()) return 0; 6 | if(dp[i][j] != -1) return dp[i][j]; 7 | // Explore for all directions 8 | int right = solveMemoization(matrix, i, j+1, maxi, dp); 9 | int bottom = solveMemoization(matrix, i+1, j, maxi, dp); 10 | int diagonal = solveMemoization(matrix, i+1, j+1, maxi, dp); 11 | 12 | // If current elment is 1 then process otherwise you cannot form sqare so return 0 13 | if(matrix[i][j] == '1'){ 14 | // 1 + because we will incluyde current block 15 | int ans = 1 + min(right, min(bottom, diagonal)); 16 | maxi = max(maxi, ans); 17 | return dp[i][j] = ans; 18 | } 19 | else{ 20 | return dp[i][j] = 0; 21 | } 22 | } 23 | public: 24 | int maximalSquare(vector>& matrix) { 25 | int maxi = 0; 26 | vector> dp(matrix.size(), vector(matrix[0].size(), -1)); 27 | solveMemoization(matrix, 0, 0,maxi, dp); 28 | return maxi * maxi; 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /DP/Maximal Square/recursion.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solve(vector>& matrix, int i, int j, int row, int col, int &maxi){ 4 | // Base case 5 | if(i >= row || j >= col) return 0; 6 | 7 | // Explore for all directions 8 | int right = solve(matrix, i, j+1, row, col, maxi); 9 | int bottom = solve(matrix, i+1, j, row, col, maxi); 10 | int diagonal = solve(matrix, i+1, j+1, row, col, maxi); 11 | 12 | // If current elment is 1 then process otherwise you cannot form sqare so return 0 13 | if(matrix[i][j] == '1'){ 14 | // 1 + because we will incluyde current block 15 | int ans = 1 + min(right, min(bottom, diagonal)); 16 | maxi = max(maxi, ans); 17 | return ans; 18 | } 19 | else{ 20 | return 0; 21 | } 22 | } 23 | public: 24 | int maximalSquare(vector>& matrix) { 25 | int i = 0; 26 | int j = 0; 27 | int maxi = 0; 28 | int row = matrix.size(); 29 | int col = matrix[0].size(); 30 | solve(matrix, i, j,row, col,maxi); 31 | return maxi * maxi; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /DP/Maximum sum of non-adjacent elements/recursion+memoization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int solveMemoization(vector &nums, int i, int n, vector&dp){ 3 | // Base case: 4 | // If exceeded size of array 5 | if(i >= n) return 0; 6 | // Step 3: If answer is already calculated return answer 7 | if(dp[i] != -1) return dp[i]; 8 | // Inclusion exclusion cases 9 | int include = solveMemoization(nums, i + 2, n, dp) + nums[i]; 10 | int exclude = solveMemoization(nums, i+1, n, dp); 11 | 12 | // Step 2: Solve and store answer in DP 13 | return dp[i] = max(include, exclude); 14 | } 15 | int maximumNonAdjacentSum(vector &nums){ 16 | int i = 0; 17 | int n = nums.size(); 18 | // Step 1: Crate DP and pass to the function call 19 | vectordp(n, -1); 20 | return solveMemoization(nums, i, n, dp); 21 | } 22 | -------------------------------------------------------------------------------- /DP/Maximum sum of non-adjacent elements/recursion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int solve(vector &nums, int i, int n){ 3 | // Base case: 4 | // If exceeded size of array 5 | if(i >= n) return 0; 6 | 7 | // Inclusion exclusion cases 8 | int include = solve(nums, i + 2, n) + nums[i]; 9 | int exclude = solve(nums, i+1, n); 10 | 11 | return max(include, exclude); 12 | } 13 | int maximumNonAdjacentSum(vector &nums){ 14 | int i = 0; 15 | int n = nums.size(); 16 | return solve(nums, i, n); 17 | } 18 | -------------------------------------------------------------------------------- /DP/Maximum sum of non-adjacent elements/space-optimization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int SO(vector &nums, int n){ 3 | int prev2 = 0; 4 | int prev1 = nums[0]; 5 | for(int i = 1 ; i < n ; i++){ 6 | int include = prev2 + nums[i]; 7 | int exclude = prev1 + 0; 8 | int curr = max(include, exclude); 9 | prev2 = prev1; 10 | prev1 = curr; 11 | } 12 | return prev1; 13 | 14 | } 15 | int maximumNonAdjacentSum(vector &nums){ 16 | int i = 0; 17 | int n = nums.size(); 18 | return SO(nums, n); 19 | } 20 | -------------------------------------------------------------------------------- /DP/Maximum sum of non-adjacent elements/tabulation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int solveTabulation(vector &nums, int n){ 3 | vectordp(n, 0); 4 | dp[0] = nums[0]; 5 | for(int i = 1 ; i < n ; i++){ 6 | int include = dp[i-2] + nums[i]; 7 | int exclude = dp[i-1] + 0; 8 | dp[i] = max(include, exclude); 9 | } 10 | return dp[n-1]; 11 | 12 | } 13 | int maximumNonAdjacentSum(vector &nums){ 14 | int i = 0; 15 | int n = nums.size(); 16 | return solveTabulation(nums, n); 17 | } 18 | -------------------------------------------------------------------------------- /DP/Min Cost Climbing Stairs/recursion+memoization.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solveMemoization(vector& cost, int n, vector&dp){ 4 | if( n == 0 ){ 5 | return cost[n]; 6 | } 7 | if( n < 0){ 8 | return 0; 9 | } 10 | if(dp[n] != -1){ 11 | return dp[n]; 12 | } 13 | return dp[n] = min(solveMemoization(cost, n-1, dp) + cost[n], solveMemoization(cost, n-2, dp) + cost[n]); 14 | } 15 | public: 16 | int minCostClimbingStairs(vector& cost) { 17 | int n = cost.size(); 18 | vectordp(n+1, -1); 19 | return min(solveMemoization(cost, n-1, dp), solveMemoization(cost, n-2, dp)); 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /DP/Min Cost Climbing Stairs/recursion.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solve(vector& cost, int n){ 4 | if( n == 0 ){ 5 | return cost[n]; 6 | } 7 | if( n < 0){ 8 | return 0; 9 | } 10 | return min(solve(cost, n-1) + cost[n], solve(cost, n-2) + cost[n]); 11 | } 12 | public: 13 | int minCostClimbingStairs(vector& cost) { 14 | int n = cost.size(); 15 | return min(solve(cost, n-1), solve(cost, n-2)); 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /DP/Min Cost Climbing Stairs/space-optimization.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solveSO(vector& cost, int n){ 4 | int prev2 = cost[0]; 5 | int prev1 = cost[1]; 6 | int curr = 0; 7 | for(int i = 2 ; i <= n; i++){ 8 | curr = min(prev2 + cost[i], prev1 + cost[i]); 9 | prev2 = prev1; 10 | prev1 = curr; 11 | } 12 | return prev1; 13 | } 14 | public: 15 | int minCostClimbingStairs(vector& cost) { 16 | int n = cost.size(); 17 | if(n == 2){ 18 | return min(cost[1], cost[0]); 19 | } 20 | return min(solveSO(cost, n-1), solveSO(cost, n-2)); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /DP/Min Cost Climbing Stairs/tabulation.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solveTab(vector& cost, int n){ 4 | vectordp(n+1); 5 | dp[0] = cost[0]; 6 | dp[1] = cost[1]; 7 | 8 | for(int i = 2 ; i <= n; i++){ 9 | dp[i] = min(dp[i - 1] + cost[i], dp[i - 2] + cost[i]); 10 | } 11 | return dp[n]; 12 | } 13 | public: 14 | int minCostClimbingStairs(vector& cost) { 15 | int n = cost.size(); 16 | // Edge case 17 | if(n == 2){ 18 | return min(cost[1], cost[0]); 19 | } 20 | return min(solveTab(cost, n-1), solveTab(cost, n-2)); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /DP/Minimum Cost For Tickets/recursion+memoization.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solveMemoization(int i, int n, vector& days, vector& costs, vector& dp){ 4 | // Base case 5 | if(i >= n) return 0; 6 | if(dp[i] != -1) return dp[i]; 7 | 8 | // Option 1: Buy 1 day pass 9 | int option1 = costs[0] + solveMemoization(i+1, n, days, costs, dp); 10 | // Option 2: Buy 7 day pass 11 | // Go seven day ahead 12 | int x; 13 | for(x = i; x < n && days[x] < days[i] + 7; x++); 14 | int option2 = costs[1] + solveMemoization(x, n, days, costs, dp); 15 | // Option 3: Buy 30 day pass 16 | for(x = i; x < n && days[x] < days[i] + 30; x++); 17 | int option3 = costs[2] + solveMemoization(x, n, days, costs, dp); 18 | 19 | return dp[i] = min(option1, min(option2, option3)); 20 | } 21 | public: 22 | int mincostTickets(vector& days, vector& costs) { 23 | int n = days.size(); 24 | int i = 0; 25 | vector dp(n+1, -1); 26 | return solveMemoization(i, n, days, costs, dp); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /DP/Minimum Cost For Tickets/recursion.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solve(int i, int n, vector& days, vector& costs){ 4 | // Base case 5 | if(i >= n) return 0; 6 | 7 | // Option 1: Buy 1 day pass 8 | int option1 = costs[0] + solve(i+1, n, days, costs); 9 | // Option 2: Buy 7 day pass 10 | // Go seven day ahead 11 | int x; 12 | for(x = i; x < n && days[x] < days[i] + 7; x++); 13 | int option2 = costs[1] + solve(x, n, days, costs); 14 | // Option 3: Buy 30 day pass 15 | for(x = i; x < n && days[x] < days[i] + 30; x++); 16 | int option3 = costs[2] + solve(x, n, days, costs); 17 | 18 | return min(option1, min(option2, option3)); 19 | } 20 | public: 21 | int mincostTickets(vector& days, vector& costs) { 22 | int n = days.size(); 23 | int i = 0; 24 | return solve(i, n, days, costs); 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /DP/Minimum Cost For Tickets/tabulation.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int tabulation(int i, int n, vector& days, vector& costs){ 4 | vector dp(n+1, INT_MAX); 5 | dp[n] = 0; 6 | 7 | for(int i = n-1 ; i >= 0 ; i--){ 8 | // Option 1: Buy 1 day pass 9 | int option1 = costs[0] + dp[i+1]; 10 | // Option 2: Buy 7 day pass 11 | // Go seven day ahead 12 | int x; 13 | for(x = i; x < n && days[x] < days[i] + 7; x++); 14 | int option2 = costs[1] + dp[x]; 15 | // Option 3: Buy 30 day pass 16 | for(x = i; x < n && days[x] < days[i] + 30; x++); 17 | int option3 = costs[2] + dp[x]; 18 | 19 | dp[i] = min(option1, min(option2, option3)); 20 | } 21 | 22 | return dp[0]; 23 | } 24 | public: 25 | int mincostTickets(vector& days, vector& costs) { 26 | int n = days.size(); 27 | int i = 0; 28 | return tabulation(i, n, days, costs); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /DP/Minimum Score Triangulation of Polygon/recursion+memoization.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solveMemoization(vector& values, int i, int j, vector>& dp){ 4 | // Base case 5 | if(i + 1 == j) return 0; 6 | if(dp[i][j] != -1) return dp[i][j]; 7 | 8 | // Select k 9 | int ans = INT_MAX; 10 | for(int k = i + 1; k <= j -1 ; k++){ 11 | int curr_ans = values[i] * values[j] * values[k] + 12 | solveMemoization(values, i, k, dp) + 13 | solveMemoization(values, k, j, dp); 14 | 15 | ans = min(ans, curr_ans); 16 | } 17 | 18 | // Return ans 19 | return dp[i][j] = ans; 20 | } 21 | public: 22 | int minScoreTriangulation(vector& values) { 23 | vector>dp(values.size(), vector(values.size(), -1)); 24 | return solveMemoization(values, 0, values.size()-1, dp); 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /DP/Minimum Score Triangulation of Polygon/recursion.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solve(vector& values, int i, int j){ 4 | // Base case 5 | if(i + 1 == j) return 0; 6 | 7 | // Select k 8 | int ans = INT_MAX; 9 | for(int k = i + 1; k <= j -1 ; k++){ 10 | int curr_ans = values[i] * values[j] * values[k] + 11 | solve(values, i, k) + 12 | solve(values, k, j); 13 | 14 | ans = min(ans, curr_ans); 15 | } 16 | 17 | // Return ans 18 | return ans; 19 | } 20 | public: 21 | int minScoreTriangulation(vector& values) { 22 | return solve(values, 0, values.size()-1); 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /DP/Minimum Score Triangulation of Polygon/tabulation.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int tabulation(vector& obs){ 4 | int n = obs.size()-1; 5 | vector> dp(3+1, vector(obs.size(), 1000000)); 6 | 7 | dp[0][n] = 0; 8 | dp[1][n] = 0; 9 | dp[2][n] = 0; 10 | dp[3][n] = 0; 11 | 12 | for(int currPos = n-1; currPos >= 0; currPos--){ 13 | for(int currLane =1; currLane <= 3; currLane++){ 14 | // check next position in same lane 15 | if(obs[currPos + 1] != currLane) dp[currLane][currPos] = dp[currLane][currPos+1]; 16 | 17 | // Side ways jump 18 | else{ 19 | int minJumps = 1000000; 20 | for(int i = 1; i <= 3; i++){ 21 | // Jump in lane only if it is not curr lane 22 | if(currLane != i){ 23 | // Jump in lane only it does not has obstacle 24 | if(obs[currPos] != i){ 25 | minJumps = min(minJumps, 1+ dp[i][currPos+1]); 26 | } 27 | } 28 | } 29 | dp[currLane][currPos] = minJumps; 30 | } 31 | } 32 | } 33 | return min(dp[2][0], min(1 + dp[1][0] , 1 + dp[3][0])); 34 | } 35 | public: 36 | int minSideJumps(vector& obstacles) { 37 | return tabulation(obstacles); 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /DP/Minimum Sideway Jumps/recursion+memoization.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solveMemoization(vector& obs, int n, int currLane, int currPos, vector>& dp){ 4 | // Base case 5 | if(currPos == n) return 0; 6 | 7 | if(dp[currLane][currPos] != -1) return dp[currLane][currPos]; 8 | 9 | // check next position in same lane 10 | if(obs[currPos + 1] != currLane) return solveMemoization(obs, n, currLane, currPos+1, dp); 11 | 12 | // Side ways jump 13 | else{ 14 | int minJumps =INT_MAX; 15 | for(int i = 1; i <= 3; i++){ 16 | // Jump in lane only if it is not curr lane 17 | if(currLane != i){ 18 | // Jump in lane only it does not has obstacle 19 | if(obs[currPos] != i){ 20 | minJumps = min(minJumps, 1+ solveMemoization(obs, n, i, currPos, dp)); 21 | } 22 | } 23 | } 24 | return dp[currLane][currPos] = minJumps; 25 | } 26 | } 27 | public: 28 | int minSideJumps(vector& obstacles) { 29 | int n = obstacles.size()-1; 30 | vector> dp(3+1, vector(obstacles.size()+1, -1)); 31 | return solveMemoization(obstacles,n, 2, 0, dp); 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /DP/Minimum Sideway Jumps/recursion.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solve(vector& obs, int n, int currLane, int currPos){ 4 | // Base case 5 | if(currPos == n) return 0; 6 | 7 | // check next position in same lane 8 | if(obs[currPos + 1] != currLane) return solve(obs, n, currLane, currPos+1); 9 | 10 | // Side ways jump 11 | else{ 12 | int minJumps =INT_MAX; 13 | for(int i = 1; i <= 3; i++){ 14 | // Jump in lane only if it is not curr lane 15 | if(currLane != i){ 16 | // Jump in lane only it does not has obstacle 17 | if(obs[currPos] != i){ 18 | minJumps = min(minJumps, 1+ solve(obs, n, i, currPos)); 19 | } 20 | } 21 | } 22 | return minJumps; 23 | } 24 | } 25 | public: 26 | int minSideJumps(vector& obstacles) { 27 | int n = obstacles.size()-1; 28 | return solve(obstacles,n, 2, 0); 29 | } 30 | }; 31 | -------------------------------------------------------------------------------- /DP/Minimum Sideway Jumps/spaceOptimization.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int SO(vector& obs){ 4 | int n = obs.size()-1; 5 | 6 | vectorcurr(4, 1000000); 7 | vectornext(4, 1000000); 8 | next[0] = 0; 9 | next[1] = 0; 10 | next[2] = 0; 11 | next[3] = 0; 12 | 13 | for(int currPos = n-1; currPos >= 0; currPos--){ 14 | for(int currLane =1; currLane <= 3; currLane++){ 15 | // check next position in same lane 16 | if(obs[currPos + 1] != currLane){ 17 | curr[currLane] = next[currLane]; 18 | } 19 | 20 | // Side ways jump 21 | else{ 22 | int minJumps = 1000000; 23 | for(int i = 1; i <= 3; i++){ 24 | // Jump in lane only if it is not curr lane 25 | if(currLane != i){ 26 | // Jump in lane only it does not has obstacle 27 | if(obs[currPos] != i){ 28 | minJumps = min(minJumps, 1 + next[i]); 29 | } 30 | } 31 | } 32 | curr[currLane] = minJumps; 33 | } 34 | } 35 | next = curr; 36 | } 37 | return min(next[2], min(1 + next[1] , 1 + next[3])); 38 | } 39 | public: 40 | int minSideJumps(vector& obstacles) { 41 | return SO(obstacles); 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /DP/Minimum Sideway Jumps/tabulation.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int tabulation(vector& obs){ 4 | int n = obs.size()-1; 5 | vector> dp(3+1, vector(obs.size(), 1000000)); 6 | 7 | dp[0][n] = 0; 8 | dp[1][n] = 0; 9 | dp[2][n] = 0; 10 | dp[3][n] = 0; 11 | 12 | for(int currPos = n-1; currPos >= 0; currPos--){ 13 | for(int currLane =1; currLane <= 3; currLane++){ 14 | // check next position in same lane 15 | if(obs[currPos + 1] != currLane) dp[currLane][currPos] = dp[currLane][currPos+1]; 16 | 17 | // Side ways jump 18 | else{ 19 | int minJumps = 1000000; 20 | for(int i = 1; i <= 3; i++){ 21 | // Jump in lane only if it is not curr lane 22 | if(currLane != i){ 23 | // Jump in lane only it does not has obstacle 24 | if(obs[currPos] != i){ 25 | minJumps = min(minJumps, 1+ dp[i][currPos+1]); 26 | } 27 | } 28 | } 29 | dp[currLane][currPos] = minJumps; 30 | } 31 | } 32 | } 33 | return min(dp[2][0], min(1 + dp[1][0] , 1 + dp[3][0])); 34 | } 35 | public: 36 | int minSideJumps(vector& obstacles) { 37 | return tabulation(obstacles); 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /DP/Painting Fence/recursion+memoization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define M 1000000007 3 | int solveMemoization(int n, int k, vector& dp) { 4 | // Base case 5 | // We have only one pole 6 | if(n == 1) return k ; 7 | if(n == 2) return (k % M + (k % M * 1ll * (k - 1) % M)) % M; 8 | if(dp[n] != -1) return dp[n]; 9 | 10 | // Recursion 11 | int last_same = (solveMemoization(n-2, k, dp) % M * 1ll * (k-1) % M) % M; 12 | int last_diff = (solveMemoization(n-1, k, dp) % M * 1ll * (k-1) % M) % M; 13 | 14 | return dp[n] = (last_same + last_diff) % M ; 15 | 16 | } 17 | 18 | int numberOfWays(int n, int k) { 19 | vector dp(n+1, -1); 20 | return solveMemoization(n, k, dp); 21 | } 22 | -------------------------------------------------------------------------------- /DP/Painting Fence/recursion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define M 1000000007 3 | int solve(int n, int k) { 4 | // Base case 5 | // We have only one pole 6 | if(n == 1) return k; 7 | if(n == 2) return (k * k) % M; 8 | 9 | // Recursion 10 | int last_same = (solve(n-2, k) * (k-1)) % M; 11 | int last_diff = (solve(n-1, k) * (k-1)) % M; 12 | 13 | return ( last_same + last_diff ) % M; 14 | 15 | } 16 | 17 | int numberOfWays(int n, int k) { 18 | return solve(n, k) % M; 19 | } 20 | -------------------------------------------------------------------------------- /DP/Painting Fence/tabulation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define M 1000000007 3 | int solveTab(int n, int k) { 4 | vector dp(n+1, -1); 5 | dp[1] = k; 6 | dp[2] = (k*k) % M; 7 | 8 | for(int i = 3; i <= n; i++){ 9 | dp[i] = ((dp[i-2] * 1ll * (k-1)) + (dp[i-1]* 1ll * (k-1))) % M; 10 | } 11 | 12 | return dp[n]; 13 | } 14 | 15 | int numberOfWays(int n, int k) { 16 | 17 | return solveTab(n, k); 18 | } 19 | -------------------------------------------------------------------------------- /DP/Perfect Squares/recursion+memoization.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solveMemoization(int n, vector& dp){ 4 | // Base case 5 | if(n == 0) return 0; 6 | if(dp[n] != -1) return dp[n]; 7 | 8 | // Initial answer 9 | int ans = INT_MAX; 10 | for(int i = 1; i * i <= n; i++){ 11 | // Answer will be minimum of ans, subproblems solution 12 | ans = min(ans, 1 + solveMemoization(n - i * i, dp)); 13 | } 14 | 15 | return dp[n] = ans; 16 | } 17 | public: 18 | int numSquares(int n) { 19 | vector dp(n+1, -1); 20 | return solveMemoization(n, dp); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /DP/Perfect Squares/recursion.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solve(int n){ 4 | // Base case 5 | if(n == 0) return 0; 6 | 7 | // Initial answer 8 | int ans = INT_MAX; 9 | for(int i = 1; i * i <= n; i++){ 10 | // Answer will be minimum of ans, subproblems solution 11 | ans = min(ans, 1 + solve(n - i * i)); 12 | } 13 | 14 | return ans; 15 | } 16 | public: 17 | int numSquares(int n) { 18 | return solve(n); 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /DP/Perfect Squares/tabulation.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int tabulation(int n){ 4 | vector dp(n+1, INT_MAX); 5 | dp[0] = 0; 6 | 7 | for(int i = 1; i <= n ; i++){ 8 | for(int j = 1; j * j <= n; j++) 9 | { 10 | // Answer will be minimum of ans, subproblems solution 11 | if(i - j*j >= 0){ 12 | dp[i] = min(dp[i], 1 + dp[i - j*j]); 13 | } 14 | } 15 | } 16 | 17 | return dp[n]; 18 | } 19 | public: 20 | int numSquares(int n) { 21 | return tabulation(n); 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /DP/Pizza With 3n Slices/recursion+memoization.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solveMemoization(vector& slices, int s, int e, int n, vector>&dp){ 4 | // Base case if slices_we_can_eat == 0 or s > e 5 | if(n == 0 || s > e) 6 | return 0; 7 | if(dp[s][n] != -1) return dp[s][n]; 8 | int include = slices[s] + solveMemoization(slices, s +2,e, n-1, dp); 9 | int exclude = solveMemoization(slices, s+1, e , n, dp); 10 | return dp[s][n] = max(include, exclude); 11 | } 12 | public: 13 | int maxSizeSlices(vector& slices) { 14 | int size = slices.size(); 15 | // Finding out the total number of slices 16 | int total_slices = size ; 17 | // As there are 3 friends each will get total/3 slices 18 | int slices_we_can_eat = total_slices / 3; 19 | vector>dp1(size+1, vector(size+1, -1)); 20 | vector>dp2(size+1, vector(size+1, -1)); 21 | 22 | int option1 = solveMemoization(slices, 0, size-2, slices_we_can_eat, dp1); 23 | int option2 = solveMemoization(slices, 1, size-1, slices_we_can_eat, dp2); 24 | 25 | return max(option1, option2); 26 | } 27 | }; 28 | -------------------------------------------------------------------------------- /DP/Pizza With 3n Slices/recursion.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solve(vector& slices, int s, int e, int n){ 4 | // Base case if slices_we_can_eat == 0 or s > e 5 | if(n == 0 || s > e) 6 | return 0; 7 | int include = slices[s] + solve(slices, s +2,e, n-1); 8 | int exclude = solve(slices, s+1, e , n); 9 | return max(include, exclude); 10 | } 11 | public: 12 | int maxSizeSlices(vector& slices) { 13 | int size = slices.size(); 14 | // Finding out the total number of slices 15 | int total_slices = size ; 16 | // As there are 3 friends each will get total/3 slices 17 | int slices_we_can_eat = total_slices / 3; 18 | 19 | int option1 = solve(slices, 0, size-2, slices_we_can_eat); 20 | int option2 = solve(slices, 1, size-1, slices_we_can_eat); 21 | 22 | return max(option1, option2); 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /DP/Reducing Dishes/recursion+memoization.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solveMemoization(vector& arr, int i, int time, vector>& dp){ 4 | if( i >= arr.size()) return 0; 5 | // Step 3: Check if answer in already calculated or not 6 | if(dp[i][time] != -1) return dp[i][time]; 7 | 8 | // Include case 9 | int include = time * arr[i] + solveMemoization(arr, i+1, time+1, dp); 10 | // Exclude case 11 | int exclude = 0 + solveMemoization(arr, i+1, time, dp); 12 | 13 | // Step 2: Store the answer indp 14 | return dp[i][time] = max(include, exclude); 15 | } 16 | public: 17 | int maxSatisfaction(vector& arr) { 18 | sort(arr.begin(), arr.end()); 19 | int time = 1; 20 | // Step 1: Create dp and pass it to recursive function call 21 | vector> dp(arr.size()+1, vector(arr.size()+1, -1)); 22 | return solveMemoization(arr, 0, time, dp); 23 | } 24 | }; 25 | -------------------------------------------------------------------------------- /DP/Reducing Dishes/recursion.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int solve(vector& arr, int i, int time){ 4 | if( i >= arr.size()) return 0; 5 | 6 | // Include case 7 | int include = time * arr[i] + solve(arr, i+1, time+1); 8 | // Exclude case 9 | int exclude = 0 + solve(arr, i+1, time); 10 | 11 | return max(include, exclude); 12 | } 13 | public: 14 | int maxSatisfaction(vector& arr) { 15 | sort(arr.begin(), arr.end()); 16 | int time = 1; 17 | return solve(arr, 0, time); 18 | } 19 | }; 20 | -------------------------------------------------------------------------------- /DP/Reducing Dishes/space-optimization.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int so(vector& arr){ 4 | int n = arr.size(); 5 | vector curr(n+1, 0); 6 | vector next(n+1, 0); 7 | for(int i = n - 1 ; i >= 0; i--){ 8 | for(int time = i ; time >= 0; time--){ 9 | // Include case 10 | int include = (time + 1)* arr[i] + next[time+1]; 11 | // Exclude case 12 | int exclude = 0 + next[time]; 13 | 14 | curr[time] = max(include, exclude); 15 | } 16 | next = curr; 17 | } 18 | return next[0]; 19 | } 20 | public: 21 | int maxSatisfaction(vector& arr) { 22 | sort(arr.begin(), arr.end()); 23 | return so(arr); 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /DP/Reducing Dishes/tabulation.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int tabulation(vector& arr){ 4 | int n = arr.size(); 5 | vector> dp(arr.size()+1, vector(arr.size()+1, 0)); 6 | for(int i = n - 1 ; i >= 0; i--){ 7 | for(int time = i ; time >= 0; time--){ 8 | // Include case 9 | int include = (time + 1)* arr[i] + dp[i+1][time+1]; 10 | // Exclude case 11 | int exclude = 0 + dp[i+1][time]; 12 | 13 | dp[i][time] = max(include, exclude); 14 | } 15 | } 16 | return dp[0][0]; 17 | } 18 | public: 19 | int maxSatisfaction(vector& arr) { 20 | sort(arr.begin(), arr.end()); 21 | return tabulation(arr); 22 | } 23 | }; 24 | -------------------------------------------------------------------------------- /DP/Subset Sum Equal To K/memoization.cpp: -------------------------------------------------------------------------------- 1 | bool solveMem(int idx, int target, vector& a, vector>& dp){ 2 | if(target == 0) return true; 3 | if(idx == 0){ 4 | if(a[idx] == target) return true; 5 | return false; 6 | } 7 | if(dp[idx][target] != -1) return dp[idx][target]; 8 | bool include = false; 9 | if(target >= a[idx]) include = solveMem(idx - 1, target - a[idx],a, dp); 10 | bool exclude = solveMem(idx - 1, target,a, dp); 11 | 12 | return dp[idx][target] = include || exclude; 13 | 14 | } 15 | bool subsetSumToK(int n, int k, vector &arr) { 16 | vector>dp(n+1, vector(k+1, -1)); 17 | return solveMem(n-1, k, arr, dp); 18 | } 19 | -------------------------------------------------------------------------------- /DP/Subset Sum Equal To K/recursion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | bool solve(int idx, int target, vector& a){ 3 | if(target == 0) return true; 4 | if(idx == 0){ 5 | if(a[idx] == target) return true; 6 | return false; 7 | } 8 | 9 | bool include = false; 10 | if(target >= a[idx]) include = solve(idx - 1, target - a[idx],a); 11 | bool exclude = solve(idx - 1, target,a); 12 | 13 | return include || exclude; 14 | 15 | } 16 | bool subsetSumToK(int n, int k, vector &arr) { 17 | return solve(n-1, k, arr); 18 | } 19 | -------------------------------------------------------------------------------- /DP/Subset Sum Equal To K/space-optimization.cpp: -------------------------------------------------------------------------------- 1 | bool SO(int n, int k, vector& a){ 2 | vectorprev(k+1, false); 3 | vectorcurr(k+1, false); 4 | prev[0] = true; 5 | curr[0] = true; 6 | prev[a[0]] = true; 7 | 8 | for(int i = 1; i < n ; i++){ 9 | for(int target = 1; target <= k; target++){ 10 | bool exclude = prev[target]; 11 | bool include = false; 12 | if(target >= a[i]) include = prev[target-a[i]]; 13 | curr[target] = include || exclude; 14 | } 15 | prev = curr; 16 | } 17 | return prev[k]; 18 | } 19 | bool subsetSumToK(int n, int k, vector &arr) { 20 | vector>dp(n+1, vector(k+1, -1)); 21 | return SO(n,k,arr); 22 | return solveTab(n,k,arr); 23 | return solveMem(n-1, k, arr, dp); 24 | } 25 | -------------------------------------------------------------------------------- /DP/Subset Sum Equal To K/tabulation.cpp: -------------------------------------------------------------------------------- 1 | bool solveTab(int n, int k, vector& a){ 2 | vector>dp(n+1, vector(k+1, false)); 3 | for(int i = 0; i < n; i++){ 4 | dp[i][0] = true; 5 | } 6 | dp[0][a[0]] = true; 7 | 8 | for(int i = 1; i < n ; i++){ 9 | for(int target = 1; target <= k; target++){ 10 | bool exclude = dp[i - 1][target]; 11 | bool include = false; 12 | if(target >= a[i]) include = dp[i - 1][target-a[i]]; 13 | dp[i][target] = include || exclude; 14 | } 15 | } 16 | return dp[n-1][k]; 17 | } 18 | bool subsetSumToK(int n, int k, vector &arr) { 19 | vector>dp(n+1, vector(k+1, -1)); 20 | return solveTab(n,k,arr); 21 | } 22 | -------------------------------------------------------------------------------- /Diamond Problem/problem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | class A{ 4 | public: 5 | int a; 6 | }; 7 | class B1: public A{ 8 | public: 9 | int b1; 10 | }; 11 | class B2: public A{ 12 | public: 13 | int b2; 14 | }; 15 | class C: public B1, public B2{ 16 | public: 17 | int c; 18 | }; 19 | int main(){ 20 | C obj; 21 | cout< 2 | using namespace std; 3 | class A{ 4 | public: 5 | int a; 6 | }; 7 | class B1: virtual public A{ 8 | public: 9 | int b1; 10 | }; 11 | class B2: virtual public A{ 12 | public: 13 | int b2; 14 | }; 15 | class C: public B1, public B2{ 16 | public: 17 | int c; 18 | }; 19 | int main(){ 20 | C obj; 21 | cout< &dp) 5 | { 6 | // Base case 7 | if (n == 1) 8 | return 1; 9 | if (n == 0) 10 | return 0; 11 | 12 | // Step 4: ANALYZE BC 13 | if (dp[n] != -1) 14 | return dp[n]; 15 | 16 | // RECURSIVE CALL 17 | int ans = solve(n - 1, dp) + solve(n - 2, dp); 18 | 19 | // Step 3: UPDATYE 20 | return dp[n] = ans; 21 | } 22 | int solveTab(int n) 23 | { 24 | // Step 1: 25 | vector dp(n + 1, -1); 26 | // Step 2: 27 | dp[1] = 1; 28 | dp[0] = 0; 29 | 30 | // Step 3: Filing 31 | for (int i = 2; i <= n; i++) 32 | { 33 | dp[i] = dp[i - 1] + dp[i - 2]; 34 | } 35 | return dp[n]; 36 | } 37 | 38 | int SO(int n) 39 | { 40 | // Step 2: 41 | int prev2 = 0; 42 | int prev1 = 1; 43 | int curr = 1; 44 | // Step 3: Filing 45 | for (int i = 2; i <= n; i++) 46 | { 47 | curr = prev1 + prev2; 48 | prev2 = prev1; 49 | prev1 = curr; 50 | } 51 | return curr; 52 | } 53 | 54 | public: 55 | int fib(int n) 56 | { 57 | // Step 1: CREATE 58 | // vector dp(n+1, -1); 59 | // Step 2: PASS 60 | if (n == 0) 61 | { 62 | return 0; 63 | } 64 | return SO(n); 65 | } 66 | }; -------------------------------------------------------------------------------- /Dynamic Programming/1D DP/House_Robber.cpp: -------------------------------------------------------------------------------- 1 | class Solution 2 | { 3 | private: 4 | int houseRobber(int i, vector &nums, vector &dp) 5 | { 6 | if (i < 0) 7 | { 8 | return 0; 9 | } 10 | if (dp[i] != -1) 11 | { 12 | return dp[i]; 13 | } 14 | 15 | int robCurrHouse = nums[i] + houseRobber(i - 2, nums, dp); 16 | int doNotRobCurrHouse = 0 + houseRobber(i - 1, nums, dp); 17 | 18 | return dp[i] = max(robCurrHouse, doNotRobCurrHouse); 19 | } 20 | int tabHouseRobber(vector &nums) 21 | { 22 | int n = nums.size(); 23 | vector dp(n, 0); 24 | dp[0] = nums[0]; 25 | 26 | for (int i = 1; i < n; i++) 27 | { 28 | int robCurrHouse = nums[i]; 29 | int doNotRobCurrHouse = INT_MIN; 30 | if (i >= 2) 31 | { 32 | robCurrHouse = nums[i] + dp[i - 2]; 33 | } 34 | if (i >= 1) 35 | { 36 | doNotRobCurrHouse = 0 + dp[i - 1]; 37 | } 38 | 39 | dp[i] = max(robCurrHouse, doNotRobCurrHouse); 40 | } 41 | 42 | return dp[n - 1]; 43 | } 44 | 45 | public: 46 | int rob(vector &nums) 47 | { 48 | return tabHouseRobber(nums); 49 | int n = nums.size(); 50 | vector dp(n, -1); 51 | return houseRobber(n - 1, nums, dp); 52 | } 53 | }; -------------------------------------------------------------------------------- /Dynamic Programming/1D DP/House_Robber_II.cpp: -------------------------------------------------------------------------------- 1 | // MEMO 2 | class Solution 3 | { 4 | private: 5 | int solve(int end, int idx, vector &nums, vector &dp) 6 | { 7 | if (idx == end) 8 | { 9 | return nums[idx]; 10 | } 11 | if (idx < end) 12 | { 13 | return 0; 14 | } 15 | if (dp[idx] != -1) 16 | { 17 | return dp[idx]; 18 | } 19 | 20 | int rob = nums[idx] + solve(end, idx - 2, nums, dp); 21 | int no_rob = 0 + solve(end, idx - 1, nums, dp); 22 | 23 | return dp[idx] = max(rob, no_rob); 24 | } 25 | 26 | public: 27 | int rob(vector &nums) 28 | { 29 | int n = nums.size(); 30 | if (n == 1) 31 | { 32 | return nums[0]; 33 | } 34 | vector dp1(n, -1); 35 | vector dp2(n, -1); 36 | int op1 = solve(0, n - 2, nums, dp1); 37 | int op2 = solve(1, n - 1, nums, dp2); 38 | 39 | return max(op1, op2); 40 | } 41 | }; -------------------------------------------------------------------------------- /Dynamic Programming/1D DP/Minimal_Cost.cpp: -------------------------------------------------------------------------------- 1 | // MEMO 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | unordered_map memo; 9 | 10 | int solve(int n, int k, vector &height) 11 | { 12 | if (n == 0) 13 | { 14 | return 0; 15 | } 16 | 17 | if (memo.find(n) != memo.end()) 18 | { 19 | return memo[n]; 20 | } 21 | 22 | int op = INT_MAX; 23 | for (int i = 1; i <= k; i++) 24 | { 25 | int curr_ans = INT_MAX; 26 | if (n - i >= 0) 27 | { 28 | curr_ans = abs(height[n] - height[n - i]) + solve(n - i, k, height); 29 | } 30 | op = min(op, curr_ans); 31 | } 32 | 33 | memo[n] = op; 34 | return op; 35 | } 36 | 37 | int minimizeCost(int n, int k, vector &height) 38 | { 39 | memo.clear(); 40 | return solve(n - 1, k, height); 41 | } 42 | -------------------------------------------------------------------------------- /Dynamic Programming/2D 3D DP - DP ON GRIDS/Minimum_Falling_Path_Sum.cpp: -------------------------------------------------------------------------------- 1 | // memo 2 | class Solution 3 | { 4 | private: 5 | int solve(int i, int j, vector> &matrix, int n, vector> &dp) 6 | { 7 | if (j < 0 || j >= n) 8 | { 9 | return 100001; 10 | } 11 | if (i == 0) 12 | { 13 | return matrix[i][j]; 14 | } 15 | if (dp[i][j] != INT_MIN) 16 | return dp[i][j]; 17 | 18 | int up = solve(i - 1, j, matrix, n, dp); 19 | int d1 = solve(i - 1, j - 1, matrix, n, dp); 20 | int d2 = solve(i - 1, j + 1, matrix, n, dp); 21 | 22 | int ans = matrix[i][j] + min(up, min(d1, d2)); 23 | return dp[i][j] = ans; 24 | } 25 | 26 | public: 27 | int minFallingPathSum(vector> &matrix) 28 | { 29 | int n = matrix.size(); 30 | int last_row = n - 1; 31 | int ans = INT_MAX; 32 | vector> dp(n, vector(n, INT_MIN)); 33 | for (int col = 0; col < n; col++) 34 | { 35 | ans = min(ans, solve(last_row, col, matrix, n, dp)); 36 | } 37 | return ans; 38 | } 39 | }; -------------------------------------------------------------------------------- /Dynamic Programming/2D 3D DP - DP ON GRIDS/Minimum_Falling_Path_Sum_II.cpp: -------------------------------------------------------------------------------- 1 | // memo 2 | class Solution 3 | { 4 | private: 5 | int solve(int row, int col, vector> &grid, vector> &dp) 6 | { 7 | int n = grid.size(); 8 | int m = grid[0].size(); 9 | if (row >= n || col >= m) 10 | { 11 | return 1e9; 12 | } 13 | if (row == n - 1) 14 | { 15 | int curr_row_mini = 1e9; 16 | for (int new_col = 0; new_col < m; new_col++) 17 | { 18 | if (new_col != col) 19 | { 20 | curr_row_mini = min(curr_row_mini, grid[row][new_col]); 21 | } 22 | } 23 | return curr_row_mini; 24 | } 25 | if (dp[row][col + 1] != -1) 26 | { 27 | return dp[row][col + 1]; 28 | } 29 | 30 | // Pick element 31 | int ans = 1e9; 32 | for (int new_col = 0; new_col < m; new_col++) 33 | { 34 | if (new_col != col) 35 | { 36 | int remaining = grid[row][new_col] + solve(row + 1, new_col, grid, dp); 37 | ans = min(ans, remaining); 38 | } 39 | } 40 | 41 | return dp[row][col + 1] = ans; 42 | } 43 | 44 | public: 45 | int minFallingPathSum(vector> &grid) 46 | { 47 | int m = grid[0].size(); 48 | int ans = 1e9; 49 | vector> dp(grid.size(), vector(m + 1, -1)); 50 | for (int col = 0; col < m; col++) 51 | { 52 | ans = min(ans, solve(0, -1, grid, dp)); 53 | } 54 | return ans; 55 | } 56 | }; -------------------------------------------------------------------------------- /Dynamic Programming/2D 3D DP - DP ON GRIDS/Unique_Paths_II.cpp: -------------------------------------------------------------------------------- 1 | class Solution 2 | { 3 | private: 4 | int solve(int i, int j, vector> &grid, vector> &dp) 5 | { 6 | if (i == 0 && j == 0 && grid[i][j] != 1) 7 | { 8 | return 1; 9 | } 10 | if (i < 0 || j < 0 || grid[i][j] == 1) 11 | { 12 | return 0; 13 | } 14 | if (dp[i][j] != -1) 15 | return dp[i][j]; 16 | 17 | int down = solve(i - 1, j, grid, dp); 18 | int right = solve(i, j - 1, grid, dp); 19 | 20 | return dp[i][j] = down + right; 21 | } 22 | 23 | public: 24 | int uniquePathsWithObstacles(vector> &grid) 25 | { 26 | int m = grid.size(); 27 | int n = grid[0].size(); 28 | vector> dp(m, vector(n, -1)); 29 | return solve(m - 1, n - 1, grid, dp); 30 | } 31 | }; -------------------------------------------------------------------------------- /Graph/BFS.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | vector BFS(int vertex, vector> edges) 3 | { 4 | ios_base::sync_with_stdio(false); 5 | cin.tie(false); 6 | // Step 1: Create adj list (Want answer in ascending order) 7 | unordered_map> adj_list; 8 | for(auto i: edges){ 9 | adj_list[i.first].insert(i.second); 10 | adj_list[i.second].insert(i.first); 11 | } 12 | 13 | // Step 2: Create BFS traversal vector 14 | vector BFS_V; 15 | unordered_map visited; 16 | for(int i = 0 ; i < vertex; i++){ 17 | if(!visited[i]){ 18 | queue q; 19 | q.push(i); 20 | visited[i] = true; 21 | while(!q.empty()) 22 | { 23 | int node = q.front(); 24 | q.pop(); 25 | BFS_V.push_back(node); 26 | for(auto i: adj_list[node]) 27 | { 28 | if(!visited[i]) 29 | { 30 | q.push(i); 31 | visited[i] = true; 32 | } 33 | } 34 | } 35 | } 36 | } 37 | return BFS_V; 38 | } 39 | -------------------------------------------------------------------------------- /Graph/Bridges-In-A-Graph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | void dfs(int node, int parent, int& timer,vector& disc, vector& low, vector>& result, vector& visited, unordered_map>&adj_list){ 3 | visited[node] = true; 4 | disc[node] = low[node] = timer++; 5 | for(auto neighbour: adj_list[node]){ 6 | if(neighbour == parent){ 7 | continue; 8 | } 9 | if(!visited[neighbour]){ 10 | dfs(neighbour, node, timer, disc, low, result, visited, adj_list); 11 | low[node] = min(low[node], low[neighbour]); 12 | // Check iof bridge 13 | if(low[neighbour]> disc[node]){ 14 | vector ans; 15 | ans.push_back(node); 16 | ans.push_back(neighbour); 17 | result.push_back(ans); 18 | } 19 | } 20 | else{ 21 | // Back edgs 22 | low[node] = min(low[node], disc[neighbour]); 23 | } 24 | 25 | } 26 | } 27 | vector> findBridges(vector> &edges, int v, int e) { 28 | // Adj_list 29 | unordered_map>adj_list; 30 | for(auto i: edges){ 31 | adj_list[i[0]].push_back(i[1]); 32 | adj_list[i[1]].push_back(i[0]); 33 | } 34 | int timer =0; 35 | vector disc(v, -1); 36 | vector low(v, -1); 37 | int parent = -1; 38 | vector visited(v,false); 39 | vector> result; 40 | // DFS 41 | for(int i = 0 ; i < v; i++){ 42 | if(!visited[i]){ 43 | dfs(i, parent, timer, disc, low, result, visited, adj_list); 44 | } 45 | } 46 | return result; 47 | } 48 | -------------------------------------------------------------------------------- /Graph/Count-Strongly-Connected-Components-Kosaraju’sAlgorithm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | void dfs(int node, 4 | unordered_map>& adj_list, 5 | stack& st, 6 | vector&visited) 7 | { 8 | visited[node] = true; 9 | for(auto i: adj_list[node]){ 10 | if(!visited[i]){ 11 | dfs(i, adj_list, st, visited); 12 | } 13 | } 14 | st.push(node); 15 | } 16 | 17 | void reversed_dfs(int node, 18 | unordered_map>& adj_list, 19 | vector&visited){ 20 | visited[node] = true; 21 | for(auto i: adj_list[node]){ 22 | if(!visited[i]){ 23 | reversed_dfs(i, adj_list, visited); 24 | } 25 | } 26 | } 27 | 28 | int stronglyConnectedComponents(int v, vector> &edges) 29 | { 30 | // Adjacency list 31 | unordered_map>adj_list; 32 | for(auto i: edges){ 33 | adj_list[i[0]].push_back(i[1]); 34 | } 35 | 36 | // Topological sort 37 | stackst; 38 | vectorvisited(v, false); 39 | for(int i = 0 ; i < v; i++){ 40 | if(!visited[i]){ 41 | dfs(i, adj_list, st, visited); 42 | } 43 | } 44 | 45 | // Transpose of graph 46 | unordered_map>transposted; 47 | for(int i = 0 ; i < v ; i++){ 48 | visited[i] = false; 49 | for(auto neighbour: adj_list[i]){ 50 | transposted[neighbour].push_back(i); 51 | } 52 | } 53 | 54 | // Dfs call for transposed graph 55 | int ans = 0; 56 | while(!st.empty()){ 57 | int top = st.top(); 58 | st.pop(); 59 | if(!visited[top]){ 60 | ans++; 61 | reversed_dfs(top,transposted, visited); 62 | } 63 | } 64 | return ans; 65 | } 66 | -------------------------------------------------------------------------------- /Graph/Cycle-Detection-Undirected-graph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | bool isCyclicBFS(int i, unordered_map>&adj_lst, unordered_map& visited, unordered_map& nodeToParent){ 3 | queueq; 4 | q.push(i); 5 | nodeToParent[i] = -1; 6 | visited[i] = true; 7 | while(!q.empty()){ 8 | int node = q.front(); 9 | q.pop(); 10 | for(auto i: adj_lst[node]){ 11 | if(visited[i] == true && nodeToParent[node] != i){ 12 | return true; 13 | } 14 | else if(!visited[i]){ 15 | visited[i] = true; 16 | nodeToParent[i] = node; 17 | q.push(i); 18 | } 19 | } 20 | } 21 | return false; 22 | } 23 | string cycleDetection (vector>& edges, int n, int m) 24 | { 25 | // Create Adjacency list 26 | unordered_map>adj_lst; 27 | for(int i = 0 ; i < edges.size(); i++){ 28 | adj_lst[edges[i][0]].emplace(edges[i][1]); 29 | adj_lst[edges[i][1]].emplace(edges[i][0]); 30 | } 31 | 32 | // BFS 33 | unordered_mapvisited; 34 | unordered_mapnodeToParent; 35 | for(int i = 0 ; i < n ; i++){ 36 | if(!visited[i]){ 37 | if(isCyclicBFS(i, adj_lst, visited, nodeToParent)){ 38 | return "Cycle Present"; 39 | } 40 | } 41 | } 42 | return "Cycle Not Present"; 43 | } 44 | -------------------------------------------------------------------------------- /Graph/Cycle-Detection-directed-graph-Kahn's-Algo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | int detectCycleInDirectedGraph(int n, vector < pair < int, int >> & edges) { 5 | // Create adjacency list 6 | unordered_map>adj_list; 7 | for(auto i: edges){ 8 | adj_list[i.first - 1].push_back(i.second - 1); 9 | } 10 | 11 | // Step 1: Find indegree of all nodes 12 | vectorindegree(n); 13 | for(auto i: adj_list){ 14 | for(auto j: i.second){ 15 | indegree[j]++; 16 | } 17 | } 18 | // Step 2: Push element with 0 ingree in queue 19 | queueq; 20 | for(int i = 0; i < indegree.size() ;i++){ 21 | if(indegree[i] == 0){ 22 | q.push(i); 23 | } 24 | } 25 | 26 | // Step 3: Do BFS 27 | vectorans; 28 | while(!q.empty()){ 29 | // Remove and store front 30 | int front = q.front(); 31 | q.pop(); 32 | ans.push_back(front); 33 | // Find all neightbours of front 34 | for(auto neighbour: adj_list[front]){ 35 | // As front have been removed update their indegree 36 | indegree[neighbour] -= 1; 37 | // Push the neighbours with indegree 0 in queue 38 | if(indegree[neighbour] == 0){ 39 | q.push(neighbour); 40 | } 41 | } 42 | } 43 | if(ans.size() == n){ 44 | return 0; 45 | } 46 | return 1; 47 | } 48 | -------------------------------------------------------------------------------- /Graph/Cycle-Detection-directed-graph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | bool DFScycle(int i, unordered_map>& adj_list, vector& visi, vector&dfs_visi){ 3 | visi[i] = true; 4 | dfs_visi[i] = true; 5 | for(auto node : adj_list[i]){ 6 | if(!visi[node]){ 7 | bool cycleDetected = DFScycle(node, adj_list, visi, dfs_visi); 8 | if(cycleDetected) return true; 9 | } 10 | else{ 11 | if(dfs_visi[node] == true){ 12 | return true; 13 | } 14 | } 15 | } 16 | dfs_visi[i] = false; 17 | return false; 18 | } 19 | 20 | int detectCycleInDirectedGraph(int n, vector < pair < int, int >> & edges) { 21 | // Craeting Adj list 22 | unordered_map>adj_list; 23 | for(auto i: edges){ 24 | adj_list[i.first].push_back(i.second); 25 | } 26 | // DFS CALLS 27 | vectorvisi(n, false); 28 | vectordfs_visi(n, false); 29 | for(int i = 1 ; i < n ; i++){ 30 | if(!visi[i]){ 31 | if(DFScycle(i, adj_list, visi, dfs_visi)){ 32 | return true; 33 | } 34 | } 35 | } 36 | return false; 37 | } 38 | -------------------------------------------------------------------------------- /Graph/DFS_Iterative.cpp: -------------------------------------------------------------------------------- 1 | // Iterative 2 | void DFS(int node, unordered_map> & adj_list, unordered_map& visited, vector& DFS_V){ 3 | stack st; 4 | st.push(node); 5 | while(!st.empty()){ 6 | int i = st.top(); 7 | visited[i] = true; 8 | st.pop(); 9 | DFS_V.push_back(i); 10 | for(auto x: adj_list[i]){ 11 | if(!visited[x]){ 12 | visited[x] = true; 13 | st.push(x); 14 | } 15 | } 16 | } 17 | } 18 | 19 | vector> depthFirstSearch(int v, int E, vector> &edges) 20 | { 21 | vector> ans; 22 | // Step 1: Create adj list (Want answer in ascending order) 23 | unordered_map> adj_list; 24 | for(int i = 0 ; i < edges.size(); i++){ 25 | int u = edges[i][0]; 26 | int v = edges[i][1]; 27 | adj_list[u].insert(v); 28 | adj_list[v].insert(u); 29 | } 30 | 31 | unordered_map visited; 32 | for(int i = 0 ; i < v; i++){ 33 | if(!visited[i]){ 34 | vector DFS_V; 35 | DFS(i,adj_list,visited, DFS_V); 36 | ans.push_back(DFS_V); 37 | } 38 | } 39 | return ans; 40 | } 41 | -------------------------------------------------------------------------------- /Graph/DFS_Recursion.cpp: -------------------------------------------------------------------------------- 1 | // Recursion 2 | void DFS(int node, unordered_map> & adj_list, unordered_map& visited, vector& DFS_V){ 3 | DFS_V.push_back(node); 4 | visited[node]= true; 5 | 6 | // Call for all connected node 7 | for(auto i: adj_list[node]){ 8 | if(!visited[i]){ 9 | DFS(i, adj_list, visited, DFS_V); 10 | } 11 | } 12 | } 13 | 14 | vector> depthFirstSearch(int v, int E, vector> &edges) 15 | { 16 | vector> ans; 17 | // Step 1: Create adj list (Want answer in ascending order) 18 | unordered_map> adj_list; 19 | for(int i = 0 ; i < edges.size(); i++){ 20 | int u = edges[i][0]; 21 | int v = edges[i][1]; 22 | adj_list[u].insert(v); 23 | adj_list[v].insert(u); 24 | } 25 | 26 | unordered_map visited; 27 | for(int i = 0 ; i < v; i++){ 28 | if(!visited[i]){ 29 | vector DFS_V; 30 | DFS(i,adj_list,visited, DFS_V); 31 | ans.push_back(DFS_V); 32 | } 33 | } 34 | return ans; 35 | } 36 | -------------------------------------------------------------------------------- /Graph/Disjoint_Set.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std ; 3 | class disjoint_set_rank{ 4 | private: 5 | // Rank 6 | vector rank; 7 | // Parent 8 | vector parent; 9 | public: 10 | disjoint_set_rank(int n){ 11 | this->rank.resize(n+1, 0); 12 | this->parent.resize(n+1); 13 | for(int i = 0 ; i < this->parent.size(); i++){ 14 | parent[i] = i; 15 | } 16 | } 17 | 18 | int findParent(int node){ 19 | if(this->parent[node] == node){ 20 | return node; 21 | } 22 | 23 | return this->parent[node] = findParent(this->parent[node]); 24 | } 25 | 26 | void unionByRank(int u, int v){ 27 | int parent_u = this->findParent(u); 28 | int parent_v = this->findParent(v); 29 | if(parent_u == parent_v){ 30 | return; 31 | } 32 | 33 | int rank_u = this->rank[parent_u]; 34 | int rank_v = this->rank[parent_v]; 35 | if(rank_u < rank_v){ 36 | this->parent[parent_u] = parent_v; 37 | } 38 | else if(rank_u > rank_v){ 39 | this->parent[parent_v] = parent_u; 40 | } 41 | else{ 42 | this->parent[v] = parent_u; 43 | rank[parent_v]++; 44 | } 45 | } 46 | }; 47 | int main() 48 | { 49 | disjoint_set_rank g1(7); 50 | g1.unionByRank(1,2); 51 | g1.unionByRank(2,3); 52 | g1.unionByRank(4,5); 53 | g1.unionByRank(6,7); 54 | g1.unionByRank(5,6); 55 | if(g1.findParent(1) == g1.findParent(7)){ 56 | cout<<"Same Compo"< 2 | using namespace std ; 3 | class disjoint_set_size{ 4 | private: 5 | // size 6 | vector size; 7 | // Parent 8 | vector parent; 9 | public: 10 | disjoint_set_size(int n){ 11 | this->size.resize(n+1, 0); 12 | this->parent.resize(n+1); 13 | for(int i = 0 ; i < this->parent.size(); i++){ 14 | parent[i] = i; 15 | } 16 | } 17 | 18 | int findParent(int node){ 19 | if(this->parent[node] == node){ 20 | return node; 21 | } 22 | 23 | return this->parent[node] = findParent(this->parent[node]); 24 | } 25 | 26 | void unionBySize(int u, int v){ 27 | int parent_u = this->findParent(u); 28 | int parent_v = this->findParent(v); 29 | if(parent_u == parent_v){ 30 | return; 31 | } 32 | 33 | int size_u = this->size[parent_u]; 34 | int size_v = this->size[parent_v]; 35 | if(size_u < size_v){ 36 | this->parent[parent_u] = parent_v; 37 | size[parent_v] += size[parent_u]; 38 | } 39 | else{ 40 | this->parent[parent_v] = parent_u; 41 | size[parent_u] += size[parent_v]; 42 | } 43 | } 44 | }; 45 | int main() 46 | { 47 | disjoint_set_size g1(7); 48 | g1.unionBySize(1,2); 49 | g1.unionBySize(2,3); 50 | g1.unionBySize(4,5); 51 | g1.unionBySize(6,7); 52 | g1.unionBySize(5,6); 53 | if(g1.findParent(1) == g1.findParent(7)){ 54 | cout<<"Same Compo"< 2 | bool comparator(vector& a, vector& b){ 3 | return a[2] < b[2]; 4 | } 5 | 6 | void makeSet(vector& par, vector& rank, int n){ 7 | for(int i = 0 ; i < n ; i++){ 8 | par[i] = i; 9 | } 10 | } 11 | int findParent(vector& par, int node){ 12 | // Reached final parent in the hierarchy 13 | if(par[node] == node){ 14 | return node; 15 | } 16 | // Find parent and path compression 17 | par[node] = findParent(par, par[node]); 18 | return par[node]; 19 | } 20 | void unionSet(int u, int v, vector& par, vector& rank){ 21 | u = findParent(par, u); 22 | v = findParent(par, v); 23 | 24 | if(rank[u] < rank[v]){ 25 | par[u] = v; 26 | } 27 | else if(rank[u] > rank[v]){ 28 | par[v] = u; 29 | } 30 | else{ 31 | par[v] = u; 32 | rank[u]++; 33 | } 34 | } 35 | 36 | int minimumSpanningTree(vector>& edges, int n) 37 | { 38 | sort(edges.begin(), edges.end(), comparator); 39 | vector parent(n); 40 | vector rank(n, 0); 41 | makeSet(parent, rank, n); 42 | 43 | int ans = 0; 44 | for(int i = 0 ; i< edges.size(); i++){ 45 | int u = findParent(parent, edges[i][0]); 46 | int v = findParent(parent, edges[i][1]); 47 | int wt = edges[i][2]; 48 | if(u != v){ 49 | ans += wt; 50 | unionSet(u, v, parent, rank); 51 | } 52 | } 53 | return ans; 54 | } 55 | -------------------------------------------------------------------------------- /Graph/Number-of-Distinct-islands.cpp: -------------------------------------------------------------------------------- 1 | 2 | class Solution { 3 | private: 4 | void DFS(int srcx, int srcy, int i, int j, vector>& grid, vector>&visited,vector>& curr_path, vector>& distance ){ 5 | if(i < 0 || j < 0 || i >= grid.size() || j >= grid[0].size() || visited[i][j] || grid[i][j] == 0){ 6 | return; 7 | } 8 | visited[i][j] = true; 9 | curr_path.push_back({i - srcx, j - srcy}); 10 | for(auto d: distance){ 11 | DFS(srcx, srcy, i + d[0], j + d[1], grid, visited, curr_path, distance); 12 | } 13 | } 14 | public: 15 | int countDistinctIslands(vector>& grid) { 16 | int r = grid.size(); 17 | int c = grid[0].size(); 18 | vector>visited(r, vector(c, false)); 19 | set>>set; 20 | vector>distance = {{1,0},{-1,0},{0,1},{0,-1}}; 21 | for(int i = 0 ; i < r; i++){ 22 | for(int j = 0 ; j < c; j++){ 23 | if(!visited[i][j] && grid[i][j] == 1){ 24 | vector>curr_path; 25 | DFS(i, j, i, j, grid, visited, curr_path, distance); 26 | set.emplace(curr_path); 27 | } 28 | } 29 | } 30 | return set.size(); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /Graph/Shortest-path-unweighted-undirected-graph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | vector shortestPath( vector> edges , int n , int m, int s , int t){ 4 | // Create adjacency list 5 | unordered_map>adj_list; 6 | for(auto i: edges){ 7 | adj_list[i.first].push_back(i.second); 8 | adj_list[i.second].push_back(i.first); 9 | } 10 | // Bfs traversal 11 | // Keep track of parent 12 | vectorparent(n+1, -1); 13 | unordered_map visited; 14 | queueq; 15 | q.push(s); 16 | visited[s] = true; 17 | // BFS logic 18 | while(!q.empty()){ 19 | int par = q.front(); 20 | visited[par] = true; 21 | q.pop(); 22 | for(auto i: adj_list[par]){ 23 | if(!visited[i]){ 24 | parent[i] = par; 25 | visited[i] = true; 26 | q.push(i); 27 | } 28 | } 29 | } 30 | // Create answer 31 | vector ans; 32 | // As parent of source is -1 33 | while(t != -1){ 34 | ans.push_back(t); 35 | t = parent[t]; 36 | } 37 | // We are traveling from destination to source 38 | reverse(ans.begin(), ans.end()); 39 | return ans; 40 | } 41 | -------------------------------------------------------------------------------- /Graph/bellmonFord-algo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int bellmonFord(int n, int m, int src, int dest, vector> &edges) { 3 | // Initially the distance will be infinity 4 | int infinity = int(1e9); 5 | // Vector to store the distance 6 | vector distance(n+1, infinity); 7 | // let distance of source be 0. 8 | distance[src] = 0; 9 | 10 | // N-1 checks 11 | for(int i = 1; i <= n; i++){ 12 | // Traverse all nodes 13 | for(int j = 0 ; j < m ; j++){ 14 | int u = edges[j][0]; 15 | int v = edges[j][1]; 16 | int wt = edges[j][2]; 17 | 18 | if(distance[u] != int(1e9) 19 | && 20 | distance[u] + wt < distance[v] 21 | ){ 22 | distance[v] = distance[u] + wt; 23 | } 24 | } 25 | } 26 | // Final check for negative cycle 27 | bool flag = false; 28 | // Traverse all nodes 29 | for(int j = 0 ; j < m ; j++){ 30 | int u = edges[j][0]; 31 | int v = edges[j][1]; 32 | int wt = edges[j][2]; 33 | 34 | if(distance[u] != int(1e9) 35 | && 36 | distance[u] + wt < distance[v] 37 | ){ 38 | flag = true; 39 | } 40 | } 41 | if(!flag){ 42 | return distance[dest]; 43 | } 44 | else{ 45 | return -1; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Graph/cycle-in-starGraph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std ; 3 | // The node with outdegree == indegree == n-1 will be the center of Star Graph 4 | class Solution { 5 | public: 6 | int findCenter(vector >& edges) { 7 | ios_base::sync_with_stdio(0); 8 | cin.tie(0); 9 | int n = INT_MIN; 10 | // Keep track of out and in degree of each vertex 11 | unordered_mapout_deg; 12 | unordered_mapin_deg; 13 | // LOOP to set degree of each vertex 14 | for(auto i: edges){ 15 | out_deg[i[0]]++; 16 | in_deg[i[1]]++; 17 | // Given graph is undirected 18 | out_deg[i[1]]++; 19 | in_deg[i[0]]++; 20 | // Finding number of vertices in graph 21 | n = max(n, max(i[1], i[0])); 22 | } 23 | for(int i = 1; i<=n; i++){ 24 | // if for a node outdegree == indegree == n-1 then its center 25 | if(out_deg[i] == in_deg[i] && out_deg[i] == n-1){ 26 | return i; 27 | } 28 | } 29 | return -1; 30 | } 31 | }; 32 | 33 | int main() 34 | { 35 | vector > edges{ 36 | {1,2}, 37 | {2,3}, 38 | {4,2} 39 | }; 40 | Solution s1; 41 | cout< 2 | vector dijkstra(vector> &vec, int vertices, int edges, int src) { 3 | ios_base::sync_with_stdio(0); 4 | cin.tie(0); 5 | // Create adj_list 6 | unordered_map>> adj_list; 7 | for(auto i: vec){ 8 | adj_list[i[0]].push_back(make_pair(i[1], i[2])); 9 | adj_list[i[1]].push_back(make_pair(i[0], i[2])); 10 | } 11 | // Create distance array 12 | vector dist(vertices, INT_MAX); 13 | dist[src] = 0; 14 | // Create set to store distance , node 15 | set>st; 16 | st.emplace(make_pair(0, src)); 17 | // Algorith 18 | while(!st.empty()){ 19 | // Remove top from set 20 | auto top = *(st.begin()); 21 | int distance = top.first; 22 | int node = top.second; 23 | // Reomove top from set 24 | st.erase(st.begin()); 25 | // Traverse neighbours of top node 26 | for(auto neighbour: adj_list[node]){ 27 | if(distance + neighbour.second < dist[neighbour.first]){ 28 | auto record = st.find(make_pair(dist[neighbour.first],neighbour.first)); 29 | // If record found update it 30 | if(record != st.end()){ 31 | st.erase(record); 32 | } 33 | dist[neighbour.first] = distance + neighbour.second; 34 | st.emplace(make_pair(dist[neighbour.first], neighbour.first)); 35 | } 36 | } 37 | } 38 | return dist; 39 | } 40 | -------------------------------------------------------------------------------- /Graph/graph-adj-list.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std ; 4 | 5 | class graph{ 6 | public: 7 | map > adj_list; 8 | void add_edge(int u, int v, bool isDirected){ 9 | // Create edge 10 | adj_list[u].push_back(v); 11 | if(!isDirected){ 12 | adj_list[v].push_back(u); 13 | } 14 | } 15 | 16 | void print_graph(){ 17 | for(auto i: adj_list){ 18 | cout< "; 19 | for(auto j: i.second){ 20 | cout< 2 | vector, int>> calculatePrimsMST(int n, int m, vector, int>> &g) 3 | { 4 | // Creat Adj_list 5 | unordered_map>>adj_list; 6 | for(int i = 0 ; i < g.size(); i++){ 7 | int u = g[i].first.first; 8 | int v = g[i].first.second; 9 | int weight = g[i].second; 10 | adj_list[u].push_back(make_pair(v,weight)); 11 | adj_list[v].push_back(make_pair(u,weight)); 12 | } 13 | 14 | // Create required data structures 15 | vectordist(n+1, INT_MAX); 16 | dist[1] = 0; 17 | vectorvisited(n+1,false); 18 | vector parent(n+1, -1); 19 | 20 | // Algo 21 | for(int i = 1 ; i <= n; i++){ 22 | int mini = INT_MAX; 23 | int u; 24 | // Step 1: Find min distance node 25 | for(int node = 1 ; node <= n; node++){ 26 | if(!visited[node] && dist[node] < mini){ 27 | mini = dist[node]; 28 | u = node; 29 | } 30 | } 31 | // step 2: Mark that node as visited 32 | visited[u] = true; 33 | // Step 3: Check its neighbours 34 | for(auto adj: adj_list[u]){ 35 | int v = adj.first; 36 | int wt = adj.second; 37 | if(!visited[v] && wt < dist[v]){ 38 | parent[v] = u; 39 | dist[v] = wt; 40 | } 41 | } 42 | } 43 | 44 | vector, int>>ans; 45 | for(int i = 2; i <= n ;i++){ 46 | ans.push_back(make_pair(make_pair(parent[i], i), dist[i])); 47 | } 48 | return ans; 49 | } 50 | -------------------------------------------------------------------------------- /Graph/topological-sort-Kahn's-Algo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | vector topologicalSort(vector> &edges, int v, int e) { 6 | // Create adjacency list 7 | unordered_map>adj_list; 8 | for(auto i: edges){ 9 | adj_list[i[0]].push_back(i[1]); 10 | } 11 | 12 | // Step 1: Find indegree of all nodes 13 | vectorindegree(v); 14 | for(auto i: adj_list){ 15 | for(auto j: i.second){ 16 | indegree[j]++; 17 | } 18 | } 19 | // Step 2: Push element with 0 ingree in queue 20 | queueq; 21 | for(int i = 0; i < indegree.size() ;i++){ 22 | if(indegree[i] == 0){ 23 | q.push(i); 24 | } 25 | } 26 | 27 | // Step 3: Do BFS 28 | vectorans; 29 | while(!q.empty()){ 30 | // Remove and store front 31 | int front = q.front(); 32 | q.pop(); 33 | ans.push_back(front); 34 | // Find all neightbours of front 35 | for(auto neighbour: adj_list[front]){ 36 | // As front have been removed update their indegree 37 | indegree[neighbour] -= 1; 38 | // Push the neighbours with indegree 0 in queue 39 | if(indegree[neighbour] == 0){ 40 | q.push(neighbour); 41 | } 42 | } 43 | } 44 | // Return answer 45 | return ans; 46 | } 47 | -------------------------------------------------------------------------------- /Graph/topological-sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | void dfs(int i, vector& visited, unordered_map>& adj_list, stack& st){ 3 | // Complete the dfs traversal 4 | visited[i] = true; 5 | for(auto node: adj_list[i]){ 6 | if(!visited[node]){ 7 | dfs(node, visited, adj_list, st); 8 | } 9 | } 10 | // Just before returning push the element on the stack 11 | st.push(i); 12 | } 13 | vector topologicalSort(vector> &edges, int v, int e) { 14 | // Create adjacency matrix 15 | unordered_map>adj_list; 16 | for(auto i: edges){ 17 | adj_list[i[0]].push_back(i[1]); 18 | } 19 | // Get required extra memory. 20 | vectorvisited(v, 0); 21 | stackst; 22 | for(int i = 0 ; i < v ; i++){ 23 | if(!visited[i]){ 24 | dfs(i, visited, adj_list, st); 25 | } 26 | } 27 | // Store answer int vector form stack 28 | vectorans; 29 | while(!st.empty()){ 30 | int temp = st.top(); 31 | st.pop(); 32 | ans.push_back(temp); 33 | 34 | } 35 | return ans; 36 | } 37 | -------------------------------------------------------------------------------- /Hashmap/Max-Frequency-Num.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | int maximumFrequency(vector &arr, int n) 3 | { 4 | unordered_map mp; 5 | 6 | // Craeting value->count mapping 7 | for(int i = 0 ; i < arr.size() ;i++){ 8 | if(mp.find(arr[i]) == mp.end()){ 9 | mp[arr[i]] = 1; 10 | } 11 | else{ 12 | mp[arr[i]]++; 13 | } 14 | } 15 | 16 | // Finding maximum occurring freq 17 | int maxi = INT_MIN; 18 | for(auto i: mp){ 19 | if(i.second > maxi){ 20 | maxi = i.second; 21 | } 22 | } 23 | 24 | // Return 25 | int ans = 0; 26 | for(int i = 0 ; i < arr.size() ; i++){ 27 | if(mp[arr[i]] == maxi){ 28 | ans = arr[i]; 29 | break; 30 | } 31 | } 32 | return ans; 33 | } 34 | -------------------------------------------------------------------------------- /Hashmap/map-stl.cpp: -------------------------------------------------------------------------------- 1 | // Craeting map of roll number and nams 2 | #include 3 | #include 4 | #include 5 | using namespace std ; 6 | int main() 7 | { 8 | // Creation 9 | unordered_mapu_map; 10 | 11 | // Insertion 12 | u_map[1] = "SK"; 13 | u_map[2] = "AK"; 14 | u_map[3] = "JK"; 15 | u_map[4] = "RK"; 16 | 17 | // Updation 18 | u_map[4] = "PK"; 19 | 20 | // Searcing 21 | //1. 22 | cout< "< :: iterator it = u_map.begin(); 40 | while(it != u_map.end()){ 41 | cout<first<<" -> "<second<next,k); 22 | ans += head->val * pow(2,k); 23 | k++; 24 | return ans; 25 | } 26 | public: 27 | int getDecimalValue(ListNode* head) { 28 | int k =0; 29 | return solve(head,k); 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /Linked-List/Merge_Nodes_in_Between_Zeros.cpp: -------------------------------------------------------------------------------- 1 | // Approach: 2 | // We will solve for nodes between the first two 0s and recursion will solve the remaining list. 3 | 4 | // Base Case: 5 | // If there is no node left OR if no next node is left in the list then return the current head. 6 | 7 | // Processing: 8 | // Step 1: We'll take the temp node pointing to the next node to head 9 | // Step 2: We will create newNode and we will go on updating the value of newNode till temp's value does not become 0 10 | // And once temp's value becomes zero we will call recursion 11 | 12 | // Recursive call: 13 | // First, we will need to check if temp->next != NULL (Meaning whether temp is the last node of the list or not) 14 | // Now recursion will solve further list and we will attach our newNode to the answer of recursion. 15 | 16 | // Finally, we will return the newNode. 17 | 18 | class Solution { 19 | //RECURSIVE SOLUTION 20 | public: 21 | ListNode* mergeNodes(ListNode* head) { 22 | // For fast i/o operation 23 | ios_base::sync_with_stdio(false); 24 | cin.tie(nullptr); 25 | 26 | // Base Case 27 | if(head == NULL || head->next == NULL){ 28 | return head; 29 | } 30 | 31 | //PROCESSING 32 | ListNode* temp = head->next; 33 | ListNode * newNode = new ListNode(0); 34 | while(temp != NULL && temp->val != 0){ 35 | newNode->val += temp->val; 36 | temp = temp->next; 37 | } 38 | 39 | //RECURSIVE CALL 40 | if(temp->next != NULL){ 41 | newNode->next = mergeNodes(temp); 42 | } 43 | 44 | //RETURN ANSWER 45 | return newNode; 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /Linked-List/PartitionList.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * struct ListNode { 4 | * int val; 5 | * ListNode *next; 6 | * ListNode() : val(0), next(nullptr) {} 7 | * ListNode(int x) : val(x), next(nullptr) {} 8 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 9 | * }; 10 | */ 11 | 12 | /* 13 | TC - O(N) 14 | SC - O(N) 15 | Approach 16 | Construct two lists one ontaining all the less elements and one containing all the greater or equal elements and then attach two lists 17 | */ 18 | class Solution { 19 | private: 20 | void insertAtTail(ListNode* &head, ListNode* &tail , int data){ 21 | ListNode* n1 = new ListNode(data); 22 | if(head == NULL){ 23 | head = n1; 24 | tail = n1; 25 | } 26 | else{ 27 | tail->next = n1; 28 | tail = n1; 29 | } 30 | } 31 | public: 32 | ListNode* partition(ListNode* head, int x) { 33 | if(head == NULL || head->next == NULL) 34 | return head; 35 | ios_base::sync_with_stdio(false); 36 | cin.tie(nullptr); 37 | ListNode* lessHead = NULL; 38 | ListNode* lessTail = NULL; 39 | ListNode* greaterEqualHead = NULL; 40 | ListNode* greaterEqualTail = NULL; 41 | ListNode* temp = head; 42 | while(temp != NULL){ 43 | if(temp->val < x){ 44 | insertAtTail(lessHead , lessTail , temp->val); 45 | } 46 | else{ 47 | insertAtTail(greaterEqualHead , greaterEqualTail, temp->val); 48 | } 49 | temp = temp->next; 50 | } 51 | if(lessHead == NULL){ 52 | return greaterEqualHead; 53 | } 54 | lessTail->next = greaterEqualHead; 55 | return lessHead; 56 | } 57 | }; 58 | -------------------------------------------------------------------------------- /Linked-List/RemoveDuplicatesFromUnsortedLL.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | Following is the class structure of the Node class: 3 | class Node 4 | { 5 | public: 6 | int data; 7 | Node *next; 8 | Node(int data) 9 | { 10 | this->data = data; 11 | this->next = NULL; 12 | } 13 | }; 14 | *****************************************************************/ 15 | #include 16 | Node *removeDuplicates(Node *head) 17 | { 18 | if(head == NULL || head->next == NULL){ 19 | return head; 20 | } 21 | Node* curr = head; 22 | Node* prev = NULL; 23 | unordered_map map; 24 | while(curr != NULL){ 25 | if(map.find(curr->data) == map.end()){ 26 | //Element not found in map 27 | map.emplace(curr->data, true); 28 | prev = curr; 29 | curr = curr->next; 30 | } 31 | else if(map[curr->data] == true){ 32 | // Element found in map 33 | prev->next = curr->next; 34 | curr = curr->next; 35 | } 36 | } 37 | return head; 38 | } 39 | -------------------------------------------------------------------------------- /Linked-List/Reverse-DLL.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | class Node 4 | { 5 | public: 6 | int data; 7 | Node *next,*prev; 8 | }; 9 | void insertAtStart(Node *&start, int data) 10 | { 11 | Node *n1 = new Node; 12 | n1->data = data; 13 | n1->next = start; 14 | n1->prev = NULL; 15 | start = n1; 16 | } 17 | void reverseDLL(Node* &head){ 18 | Node* current = head; 19 | Node* prev = current->prev; 20 | Node* next = current->next; 21 | while(current != NULL){ 22 | next = current->next; 23 | current->next = prev; 24 | current->prev =next; 25 | prev = current; 26 | current = next; 27 | } 28 | head = prev; 29 | } 30 | void displayList(Node *start) 31 | { 32 | if (start == NULL) 33 | { 34 | cout << "\nUnderFlow\n"; 35 | return; 36 | } 37 | Node *temp; 38 | temp = start; 39 | while (temp->next != NULL) 40 | { 41 | cout << temp->data << " <=> "; 42 | temp = temp->next; 43 | } 44 | cout << temp->data; 45 | } 46 | int main() 47 | { 48 | Node* start = NULL; 49 | insertAtStart(start, 10); 50 | insertAtStart(start, 20); 51 | insertAtStart(start, 30); 52 | insertAtStart(start, 40); 53 | cout<<"BEFORE: "; 54 | displayList(start); 55 | reverseDLL(start); 56 | cout< 2 | using namespace std; 3 | class Node 4 | { 5 | public: 6 | int data; 7 | Node *next; 8 | }; 9 | void insertAtStart(Node *&start, int data) 10 | { 11 | Node *n1 = new Node; 12 | n1->data = data; 13 | n1->next = start; 14 | start = n1; 15 | } 16 | void displayList(Node *start) 17 | { 18 | if (start == NULL) 19 | { 20 | cout << "\nUnderFlow\n"; 21 | return; 22 | } 23 | Node *temp; 24 | temp = start; 25 | while (temp->next != NULL) 26 | { 27 | cout << temp->data << " -> "; 28 | temp = temp->next; 29 | } 30 | cout << temp->data<next == NULL) 35 | { 36 | return; // Checking for Empty or single node LL 37 | } 38 | // Using 3 ptr approach 39 | Node *current = head; 40 | Node *previous = NULL; 41 | Node *next = current->next; 42 | while (current != NULL) 43 | { 44 | next = current->next; 45 | current->next = previous; 46 | previous = current; 47 | current = next; 48 | } 49 | head = previous; 50 | } 51 | void reverseLL2(Node *&head) 52 | { 53 | if (head == NULL || head->next == NULL) 54 | { 55 | return; // Checking for Empty or single node LL 56 | } 57 | //Recursion will reverse list from head->next 58 | reverseLL2(head->next); 59 | 60 | //Our job is to reverse first Node 61 | head->next->next = head; 62 | head->next = NULL; 63 | } 64 | int main() 65 | { 66 | Node* start = NULL; 67 | insertAtStart(start, 10); 68 | insertAtStart(start, 20); 69 | insertAtStart(start, 30); 70 | insertAtStart(start, 40); 71 | cout<<"BEFORE: "; 72 | displayList(start); 73 | reverseLL(start); 74 | cout<<"AFTER: "; 75 | displayList(start); 76 | return 0; 77 | } 78 | -------------------------------------------------------------------------------- /Linked-List/XOR_Linked_List.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Structure of linked list is as 4 | struct Node 5 | { 6 | int data; 7 | struct Node* npx; 8 | 9 | Node(int x){ 10 | data = x; 11 | npx = NULL; 12 | } 13 | }; 14 | 15 | Utility function to get XOR of two Struct Node pointer 16 | use this function to get XOR of two pointers 17 | struct Node* XOR (struct Node *a, struct Node *b) 18 | { 19 | return (struct Node*) ((uintptr_t) (a) ^ (uintptr_t) (b)); 20 | } 21 | */ 22 | // function should insert the data to the front of the list 23 | struct Node *insert(struct Node *head, int data) { 24 | Node* node = new Node(data); 25 | if(head == NULL){ 26 | head = node; 27 | return head; 28 | } 29 | node->npx = head; 30 | head->npx = XOR(head->npx, node); 31 | head = node; 32 | return head; 33 | } 34 | 35 | vector printList(struct Node *head) { 36 | vector ans; 37 | Node* curr = head; 38 | Node* prev = NULL; 39 | while(curr){ 40 | ans.push_back(curr->data); 41 | Node* next = XOR(prev,curr->npx); 42 | prev = curr; 43 | curr = next; 44 | } 45 | return ans; 46 | } 47 | -------------------------------------------------------------------------------- /Linked-List/addTwoNumbers.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * struct ListNode { 4 | * int val; 5 | * ListNode *next; 6 | * ListNode() : val(0), next(nullptr) {} 7 | * ListNode(int x) : val(x), next(nullptr) {} 8 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 9 | * }; 10 | */ 11 | class Solution { 12 | private: 13 | void insertAtTail(ListNode* &ansHead,ListNode* &ansTail,int f_sum){ 14 | ListNode *n1 = new ListNode(f_sum); 15 | if(ansHead == NULL){ 16 | ansHead = n1; 17 | ansTail = n1; 18 | return; 19 | } 20 | ansTail->next = n1; 21 | ansTail = n1; 22 | } 23 | public: 24 | ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { 25 | int carry = 0; 26 | ListNode* ansHead = NULL; 27 | ListNode* ansTail = NULL; 28 | while(l1 != NULL && l2 != NULL){ 29 | int sum = carry + l1->val + l2->val; 30 | int f_sum = sum % 10; 31 | insertAtTail(ansHead,ansTail,f_sum); 32 | carry = sum/10; 33 | l1 = l1->next; 34 | l2 = l2->next; 35 | } 36 | while(l1 != NULL){ 37 | int sum = carry + l1->val ; 38 | int f_sum = sum % 10; 39 | insertAtTail(ansHead,ansTail,f_sum); 40 | carry = sum/10; 41 | l1 = l1->next; 42 | } 43 | while(l2 != NULL){ 44 | int sum = carry + l2->val ; 45 | int f_sum = sum % 10; 46 | insertAtTail(ansHead,ansTail,f_sum); 47 | carry = sum/10; 48 | l2 = l2->next; 49 | } 50 | if(carry != 0){ 51 | insertAtTail(ansHead,ansTail,carry); 52 | } 53 | return ansHead; 54 | } 55 | }; 56 | -------------------------------------------------------------------------------- /Linked-List/deleteDuplicates.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * struct ListNode { 4 | * int val; 5 | * ListNode *next; 6 | * ListNode() : val(0), next(nullptr) {} 7 | * ListNode(int x) : val(x), next(nullptr) {} 8 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 9 | * }; 10 | */ 11 | // i/p -> 1-1-2-2-2-3 12 | // o/p -> 1-2-3 13 | class Solution { 14 | public: 15 | ListNode* deleteDuplicates(ListNode* head) { 16 | ios_base::sync_with_stdio(false); 17 | cin.tie(NULL); 18 | cout.tie(NULL); 19 | if(head == NULL){ 20 | return NULL; 21 | } 22 | ListNode * curr = head; 23 | while(curr->next != NULL){ 24 | if(curr->next->val != curr->val){ 25 | curr = curr->next; 26 | } 27 | else{ 28 | curr->next = curr->next->next; 29 | } 30 | } 31 | return head; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /Linked-List/deleteParticularElement.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * struct ListNode { 4 | * int val; 5 | * ListNode *next; 6 | * ListNode() : val(0), next(nullptr) {} 7 | * ListNode(int x) : val(x), next(nullptr) {} 8 | * ListNode(int x, ListNode *next) : val(x), next(next) {} 9 | * }; 10 | */ 11 | class Solution { 12 | public: 13 | ListNode* removeElements(ListNode* head, int val) { 14 | if(head == NULL || (head->next ==NULL && head->val != val)) 15 | return head ; 16 | while(head != NULL && head->val == val){ 17 | head = head->next; 18 | } 19 | if(head == NULL || (head->next ==NULL && head->val != val)) 20 | return head ; 21 | ListNode* prev = head; 22 | ListNode* curr = head->next; 23 | ListNode* next = curr->next; 24 | while(curr != NULL){ 25 | next = curr->next; 26 | if(curr->val==val){ 27 | prev->next = next; 28 | } 29 | else{ 30 | prev = curr; 31 | } 32 | curr = next; 33 | } 34 | return head; 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /Linked-List/middle-of-LL.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | class Node 4 | { 5 | public: 6 | int data; 7 | Node *next; 8 | }; 9 | void insertAtStart(Node *&start, int data) 10 | { 11 | Node *n1 = new Node; 12 | n1->data = data; 13 | n1->next = start; 14 | start = n1; 15 | } 16 | void displayList(Node *start) 17 | { 18 | if (start == NULL) 19 | { 20 | cout << "\nUnderFlow\n"; 21 | return; 22 | } 23 | Node *temp; 24 | temp = start; 25 | while (temp->next != NULL) 26 | { 27 | cout << temp->data << " -> "; 28 | temp = temp->next; 29 | } 30 | cout << temp->data << endl; 31 | } 32 | 33 | 34 | int middle_of_ll(Node* start){ 35 | Node* fast = start; 36 | Node* slow = start; 37 | while(fast->next != NULL && fast->next->next != NULL){ 38 | fast = fast->next->next; 39 | slow = slow ->next; 40 | } 41 | return slow->data; 42 | } 43 | 44 | 45 | int main() 46 | { 47 | Node *start = NULL; 48 | insertAtStart(start, 5); 49 | insertAtStart(start, 4); 50 | insertAtStart(start, 3); 51 | insertAtStart(start, 2); 52 | insertAtStart(start, 1); 53 | displayList(start); 54 | cout<< middle_of_ll(start)<next != NULL){ 17 | head = head -> next; 18 | length ++; 19 | } 20 | return length; 21 | } 22 | public: 23 | ListNode* rotateRight(ListNode* head, int k) { 24 | ios_base::sync_with_stdio(false); 25 | cin.tie(NULL); 26 | cout.tie(NULL); 27 | if(head == NULL || head->next == NULL || k==0){ 28 | return head; 29 | } 30 | int length = getLength(head); 31 | /* We are finding length because though k = 5 but if list has length 3 it will only get rotated 2 times because after every 3 rotations list will be back in original form */ 32 | int newk = k % length; 33 | while(newk--) 34 | { 35 | ListNode* last = head; 36 | ListNode* prev_last = NULL; 37 | while(last-> next != NULL) 38 | { 39 | prev_last = last; 40 | last = last->next; 41 | } 42 | last->next = head ; 43 | prev_last -> next = NULL; 44 | head = last; 45 | } 46 | return head; 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /Mathematical Algorithms/Divisibility & Large Numbers/divisibilityBy3.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | bool check(string str) 4 | { 5 | int sum = 0; 6 | for (int i = 0; i < str.size(); i++) 7 | { 8 | sum += int(str[i] - '0'); 9 | } 10 | if (sum % 3 == 0) 11 | return true; 12 | return false; 13 | } 14 | int main() 15 | { 16 | string str = "122"; 17 | check(str) ? cout << "Yes" << endl : cout << "No " << endl; 18 | return 0; 19 | } -------------------------------------------------------------------------------- /Mathematical Algorithms/Divisibility & Large Numbers/divisibleBy11.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std ; 3 | 4 | class Solution{ 5 | private: 6 | long long getSum(string &s, int startIdx){ 7 | long long sum = 0; 8 | for(int i = startIdx; i < s.length(); i+=2){ 9 | sum += int(s[i] - '0'); 10 | } 11 | return sum; 12 | } 13 | public: 14 | int divisibleBy11(string s) 15 | { 16 | long long evenSum = getSum(s, 0); 17 | long long oddSum = getSum(s, 1); 18 | return abs(evenSum - oddSum) % 11 == 0; 19 | } 20 | }; 21 | int main() 22 | { 23 | Solution* q1 = new Solution(); 24 | cout<divisibleBy11("1331")< 2 | using namespace std; 3 | 4 | class Solution 5 | { 6 | private: 7 | bool solve(string num) 8 | { 9 | int n = num.length(); 10 | if (n % 3 == 1) 11 | { 12 | reverse(num.begin(), num.end()); 13 | num += "00"; 14 | reverse(num.begin(), num.end()); 15 | } 16 | else if (n % 3 == 2) 17 | { 18 | reverse(num.begin(), num.end()); 19 | num += "0"; 20 | reverse(num.begin(), num.end()); 21 | } 22 | long long sum = 0; 23 | for (int i = 0; i < num.length(); i += 3) 24 | { 25 | if (i % 2 == 0) 26 | { 27 | // Add 28 | string curr_num = num.substr(i, 3); 29 | sum += stoi(curr_num); 30 | 31 | } 32 | else 33 | { 34 | // Subtract 35 | string curr_num = num.substr(i, 3); 36 | sum -= stoi(curr_num); 37 | } 38 | } 39 | return abs(sum) % 13 == 0; 40 | } 41 | 42 | public: 43 | int divisibleBy13(string num) 44 | { 45 | return solve(num); 46 | } 47 | }; 48 | int main() 49 | { 50 | Solution *q1 = new Solution(); 51 | cout << q1->divisibleBy13("83959092724653") << endl; 52 | return 0; 53 | } -------------------------------------------------------------------------------- /Mathematical Algorithms/Divisibility & Large Numbers/divisibleBy4.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std ; 3 | 4 | class Solution{ 5 | public: 6 | int divisibleBy4(string str) 7 | { 8 | if(str.length() == 1) return stoi(str) % 4 == 0; 9 | int n = str.length(); 10 | int last = int(str[n-1] - '0'); 11 | int secondlast = int(str[n-2] - '0'); 12 | int digits = secondlast * 10 + last; 13 | return digits % 4 == 0; 14 | 15 | } 16 | }; 17 | int main() 18 | { 19 | Solution* q1 = new Solution(); 20 | cout<divisibleBy4("12")< 2 | #include 3 | using namespace std ; 4 | 5 | class Solution{ 6 | private: 7 | int solve(int a, int b, int &x, int &y){ 8 | if(a == 0){ 9 | x = 0; 10 | y = 1; 11 | return b; 12 | } 13 | int x1 = 0, y1 = 0; 14 | int gcd = solve(b % a, a, x1, y1); 15 | 16 | x = y1 - (b / a)*x1; 17 | y = x1; 18 | 19 | return gcd; 20 | } 21 | public: 22 | vector gcd(int a, int b){ 23 | int x = 0; 24 | int y = 0; 25 | int gcd = solve(a, b, x, y); 26 | return {gcd, x, y}; 27 | } 28 | }; 29 | 30 | bool compareVectors(const vector& v1, const vector& v2) { 31 | if (v1.size() != v2.size()) return false; 32 | for (size_t i = 0; i < v1.size(); ++i) { 33 | if (v1[i] != v2[i]) return false; 34 | } 35 | return true; 36 | } 37 | 38 | int main() 39 | { 40 | Solution ob; 41 | vector result = ob.gcd(35, 15); 42 | assert(compareVectors(result, {5, 1, -2})); 43 | return 0; 44 | } -------------------------------------------------------------------------------- /Mathematical Algorithms/LCM & GCD/gcdOfFloats.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std ; 3 | int main() 4 | { 5 | int a = 1.2; 6 | int b = 22.5; 7 | return 0; 8 | } -------------------------------------------------------------------------------- /Mathematical Algorithms/LCM & GCD/goodPair.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std ; 3 | int numOfDivisors(int n){ 4 | int cnt = 0; 5 | for(int i = 1; i * i <= n; i++){ 6 | if(n % i == 0){ 7 | if(n / i == i){ 8 | cnt += 1; 9 | } 10 | else{ 11 | cnt += 2; 12 | } 13 | } 14 | } 15 | return cnt; 16 | } 17 | int getAns(int n){ 18 | int cnt = 0; 19 | for(int i = 1; i <= n; i++){ 20 | cnt += numOfDivisors(i); 21 | } 22 | return cnt; 23 | } 24 | int main() 25 | { 26 | cout< 2 | using namespace std ; 3 | 4 | class Solution 5 | { 6 | #define M 1000000007 7 | private: 8 | long long getGCD(long long a, long long b) 9 | { 10 | if (a == 0) 11 | return b; 12 | return getGCD(b % a, a); 13 | } 14 | long long getLCM(long long a, long long b) 15 | { 16 | return (a * b) / getGCD(a, b); 17 | } 18 | 19 | public: 20 | int lcmOfArray(int N, int arr[]) 21 | { 22 | if (N == 1) 23 | return arr[0]; 24 | long long lcm = 0; 25 | lcm = getLCM(arr[0] * 1ll, arr[1] * 1ll) % M; 26 | for (int i = 2; i < N; i++) 27 | { 28 | lcm = getLCM(lcm, arr[i] * 1ll) % M; 29 | } 30 | return lcm; 31 | } 32 | }; 33 | 34 | int main() 35 | { 36 | Solution ob; 37 | int arr[5] = {1,2,3,4,5}; 38 | cout< 2 | using namespace std ; 3 | 4 | long long power(long long a, long long b, long long m){ 5 | long long res = 1; 6 | a = a % m; 7 | while(b > 0){ 8 | // odd power 9 | if(b & 1){ 10 | res = (res * a) % m; 11 | b = b - 1; 12 | } 13 | //even power 14 | else{ 15 | a = (a * a) % m; 16 | b /= 2; 17 | } 18 | } 19 | return res; 20 | } 21 | int main() 22 | { 23 | long long a = 3; 24 | // String input as b is very large 25 | int m = 1000000007; 26 | string b = "100000000000000000000000000"; 27 | long long rem_b = 0; 28 | 29 | // Reduce the number b to a small number using Fermat Little 30 | for(int i = 0; i < b.length(); i++ ){ 31 | rem_b = (rem_b * 10 + int(b[i])) % (m - 1); 32 | } 33 | 34 | cout< map; 9 | queue q; 10 | int n = A.length(); 11 | string ans; 12 | for (int i = 0; i < n; i++) 13 | { 14 | char ch = A[i]; 15 | // Increase the count 16 | map[ch]++; 17 | // Push in queue 18 | q.push(ch); 19 | while (!q.empty()) 20 | { 21 | if (map[q.front()] > 1) 22 | { 23 | // Repeating character 24 | q.pop(); 25 | } 26 | else 27 | { 28 | // Non repeating character 29 | ans.push_back(q.front()); 30 | break; 31 | } 32 | } 33 | if (q.empty()) 34 | { 35 | ans.push_back('#'); 36 | } 37 | } 38 | return ans; 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /Queue/circular-queue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | class CircularQueue{ 3 | private: 4 | int front; 5 | int rear; 6 | int *arr; 7 | int size; 8 | public: 9 | // Initialize your data structure. 10 | CircularQueue(int n){ 11 | this->size = n; 12 | this->arr = new int[size]; 13 | this->front = this->rear = -1; 14 | } 15 | 16 | // Enqueues 'X' into the queue. Returns true if it gets pushed into the stack, and false otherwise. 17 | bool enqueue(int value){ 18 | // Full queue 19 | if((front == 0 && rear == this->size -1) || (rear == (front-1) % (size - 1))){ 20 | //cout<<"Queue is full"; 21 | return false; 22 | } 23 | 24 | // Empty queue 25 | else if(front == -1){ 26 | front = 0; 27 | rear = 0; 28 | } 29 | 30 | // Rear end if full 31 | else if(rear == this->size - 1 && front!= 0){ 32 | rear = 0; 33 | } 34 | // Normal case 35 | else{ 36 | rear++; 37 | } 38 | arr[rear] = value; 39 | return true; 40 | } 41 | 42 | // Dequeues top element from queue. Returns -1 if the stack is empty, otherwise returns the popped element. 43 | int dequeue(){ 44 | // Empty queue 45 | if(front == -1){ 46 | return -1; 47 | } 48 | int ans = arr[front]; 49 | arr[front] = -1; 50 | if(front == rear) 51 | { 52 | // Only 1 elelement in queue 53 | front = rear = -1; 54 | } 55 | else if(front == this->size-1){ 56 | // Front at last element 57 | front = 0; 58 | } 59 | else{ 60 | // Normal case 61 | front++; 62 | } 63 | return ans; 64 | } 65 | }; 66 | -------------------------------------------------------------------------------- /Queue/circularTour.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The stucture of petrol pump 3 | struct petrolPump{ 4 | int petrol; 5 | int distance; 6 | }; 7 | */ 8 | class Solution{ 9 | public: 10 | 11 | //Function to find starting point where the truck can start to get through 12 | //the complete circle without exhausting its petrol in between. 13 | int tour(petrolPump p[],int n) 14 | { 15 | int start = 0; 16 | int balance = 0; 17 | int deficit = 0; 18 | for(int i = 0 ; i < n ; i++){ 19 | balance = balance + p[i].petrol - p[i].distance; 20 | if(balance < 0){ 21 | //Negactive balanace 22 | // Step 1: Calculate how much deficiency of petrol is there 23 | deficit = deficit + balance; 24 | // Step 2: Take start to next block 25 | start = i+1; 26 | // Step 3: Make initial balanace again 0 27 | balance = 0; 28 | } 29 | } 30 | // Step 4: Find remaining petrol after visiting last block 31 | int remaining_petrol = deficit + balance; 32 | if(remaining_petrol > 0){ 33 | //Travel is possible 34 | return start; 35 | } 36 | else{ 37 | return -1; 38 | } 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /Queue/interLeaveQueue.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | EX: Q = {1,2,3,4,5,6,7,8} 4 | Approach 1: Using Extra Queue 5 | Step 1: Fetch first half elements from queue and push them in a new queue. 6 | ``` 7 | After this your two queues will look like 8 | NewQueue -> {1,2,3,4} 9 | OqiginalQueue -> {5,6,7,8} 10 | 11 | ``` 12 | 13 | Step 2: while(!newQueue.empty()) 14 | { 15 | 1. Remove element from front of new queue and push it 16 | in original queue 17 | 2. Remove element fron front of original queue and push 18 | it in original queue 19 | } 20 | 21 | Step 3: END 22 | 23 | TC : O(N) 24 | SC : O(N) 25 | */ 26 | 27 | #include 28 | void interLeaveQueue(queue < int > & q) { 29 | int size = q.size(); 30 | int half = size / 2; 31 | int count = 0; 32 | queue newQueue; 33 | // Step 1: 34 | while(count < half){ 35 | int element = q.front(); 36 | newQueue.push(element); 37 | q.pop(); 38 | count++; 39 | } 40 | // Step 2: 41 | while(!newQueue.empty()){ 42 | //1. 43 | int newElement = newQueue.front(); 44 | q.push(newElement); 45 | newQueue.pop(); 46 | //2. 47 | int element = q.front(); 48 | q.push(element); 49 | q.pop(); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Queue/maxInSlidingWindow.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Approach using doubly ended queue to keep track of maximum element. 3 | Why Deque ? 4 | -> As when we move forward in each window what we are doing is, we are adding one element at back (push_back) and removing one element from front (pop_front). The Deque enables both of these operations to be completed in O(1) time. 5 | 6 | TC : O(N) 7 | SC : O(N) 8 | */ 9 | 10 | class Solution { 11 | public: 12 | vector maxSlidingWindow(vector& nums, int k) { 13 | ios_base::sync_with_stdio(false); 14 | cin.tie(nullptr); 15 | 16 | vector ans; 17 | deque dq; // Storing index of max elements 18 | 19 | // Traversing through input 20 | for(int i= 0 ; i< nums.size(); i++) 21 | { 22 | // Remove the elements from deque which are out of current window so if you are at i th index then i - k th index will be out of window 23 | int out_of_bound = i - k; 24 | if(!dq.empty() && dq.front() == out_of_bound){ 25 | dq.pop_front(); 26 | } 27 | 28 | // pop all smaller values from deque 29 | while(!dq.empty() && nums[dq.back()] <= nums[i]){ 30 | dq.pop_back(); 31 | } 32 | 33 | // Push the new element in deque at back 34 | dq.push_back(i); 35 | 36 | // when the first window will be complete then start storing the max 37 | if(i>= k -1){ 38 | ans.push_back(nums[dq.front()]); 39 | } 40 | } 41 | return ans; 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /Queue/queue-stl.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | int main(){ 5 | queue q; 6 | //Push operation 7 | q.push(1); 8 | q.push(5); 9 | q.push(7); 10 | q.push(9); 11 | 12 | // Size 13 | cout<<"Before pop size "< 2 | class Queue { 3 | private: 4 | int *arr; 5 | int qfront; 6 | int rear; 7 | int size; 8 | public: 9 | Queue() { 10 | this->size = 100000000; // As max size of int array can be 10^8 11 | this->arr = new int[size]; 12 | this->qfront = 0; 13 | this->rear = 0; 14 | } 15 | 16 | /*----------------- Public Functions of Queue -----------------*/ 17 | 18 | bool isEmpty() { 19 | if(qfront == rear){ 20 | return true; 21 | } 22 | return false; 23 | } 24 | 25 | void enqueue(int data) { 26 | // Implement the enqueue() function 27 | if(qfront == 0 && rear == size){ 28 | //cout<<"Queue is full"; 29 | } 30 | else{ 31 | arr[rear] = data; 32 | rear++; 33 | } 34 | } 35 | 36 | int dequeue() { 37 | if(qfront == rear){ 38 | return -1; 39 | } 40 | else{ 41 | int ans = arr[qfront]; 42 | arr[qfront] = -1; 43 | qfront++; 44 | if(qfront == rear){ 45 | qfront = 0; 46 | rear = 0; 47 | } 48 | return ans; 49 | } 50 | } 51 | 52 | int front() { 53 | if(qfront == rear){ 54 | return -1; 55 | } 56 | else{ 57 | return arr[qfront]; 58 | } 59 | } 60 | }; 61 | -------------------------------------------------------------------------------- /Queue/reverse-queue.cpp: -------------------------------------------------------------------------------- 1 | //Approach 1: Using Stack 2 | /* 3 | TC: O(N) 4 | SC: O(N) 5 | */ 6 | #include 7 | using namespace std ; 8 | void reverse(queue& q){ 9 | stack st; 10 | while(!q.empty()){ 11 | int element = q.front(); 12 | st.push(element); 13 | q.pop(); 14 | } 15 | while(!st.empty()){ 16 | int element = st.top(); 17 | cout<& q){ 30 | // Base Case 31 | if(q.empty()){ 32 | return; 33 | } 34 | 35 | // Store and remove front element aside 36 | int element = q.front(); 37 | q.pop(); 38 | 39 | // Call recursion to reverse remaining queue 40 | reverse_2(q); 41 | 42 | //cout< q; 51 | q.push(1); 52 | q.push(2); 53 | q.push(3); 54 | q.push(4); 55 | reverse(q); 56 | reverse_2(q); 57 | return 0; 58 | } 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /Queue/reverseElementsinK.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | /* 3 | Approach: n = q.size() 4 | Step 1: Reverse first k 5 | step 2: POP n-k and push in queue 6 | */ 7 | queue reverseElements(queue q, int k) 8 | { 9 | int n = q.size(); 10 | stack st; 11 | int cnt =0; 12 | while(cnt 14 | bool findRedundantBrackets(string &s) 15 | { 16 | stack st; 17 | for(int i = 0 ; i< s.length(); i++){ 18 | char ch = s[i]; 19 | if(ch == '('||ch == '+'||ch == '-'|| ch == '/'|| ch == '*'){ 20 | st.push(ch); 21 | } 22 | else{ 23 | // Either a to z or ) 24 | if(ch == ')') 25 | { 26 | char top = st.top(); 27 | if(top == '+'||top == '-'|| top == '/'|| top == '*') 28 | { 29 | if(!st.empty() ) 30 | while(st.top() != '('){ 31 | st.pop(); 32 | } 33 | st.pop(); 34 | } 35 | else 36 | { 37 | return true; 38 | } 39 | } 40 | else{ 41 | continue; 42 | } 43 | } 44 | } 45 | return false; 46 | } 47 | -------------------------------------------------------------------------------- /Stack/Valid-Parentheses.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | //Push Down Automata Logic 3 | public: 4 | bool isValid(string s) { 5 | ios_base::sync_with_stdio(false); 6 | cin.tie(nullptr); 7 | // If length of string is 1 its definietly not valid 8 | if(s.length() == 1) 9 | return false; 10 | int n = s.length(); 11 | stack stack; 12 | for(int i = 0 ; i< n ; i++){ 13 | // for every ( , { , [ we will push it to stack 14 | if(s[i] == '(' || s[i] == '{' || s[i] == '['){ 15 | stack.push(s[i]); 16 | } 17 | 18 | // for every ) ,},] we will check if top of stack is opening pranthesis or NOT 19 | else if(s[i] == ')'){ 20 | if(!stack.empty() && stack.top() == '('){ 21 | stack.pop(); 22 | } 23 | else{ 24 | return false; 25 | } 26 | } 27 | else if(s[i] == '}'){ 28 | if(!stack.empty() && stack.top() == '{'){ 29 | stack.pop(); 30 | } 31 | else{ 32 | return false; 33 | } 34 | } 35 | else if(s[i] == ']'){ 36 | if(!stack.empty() && stack.top() == '['){ 37 | stack.pop(); 38 | } 39 | else{ 40 | return false; 41 | } 42 | } 43 | } 44 | // After ending string if stack is empty we can say input is valid 45 | if(stack.empty()){ 46 | return true; 47 | } 48 | return false; 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /Stack/deleteMiddle.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Delete middle element from stack 3 | Problem Statement : You are having a stack "ARR" of size 'N+1', your task is to delete the middlemost element so 4 | that the size of resulting stack is 'N'. 5 | */ 6 | 7 | void solve(stack&inputStack, int size ,int count = 0){ 8 | // Base Case 9 | if(count == size/2){ 10 | inputStack.pop(); 11 | return; 12 | } 13 | // Otherwise 14 | // Store and remove the top element 15 | int topElement = inputStack.top(); 16 | inputStack.pop(); 17 | solve(inputStack,size,count+1); 18 | 19 | //And before returning push the top element again in stack 20 | inputStack.push(topElement); 21 | } 22 | void deleteMiddle(stack&inputStack, int N){ 23 | solve(inputStack,N); 24 | } 25 | -------------------------------------------------------------------------------- /Stack/minAddToMakeValidBrackets.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | A parentheses string is valid if and only if: 3 | 4 | It is the empty string, 5 | It can be written as AB (A concatenated with B), where A and B are valid strings, or 6 | It can be written as (A), where A is a valid string. 7 | You are given a parentheses string s. In one move, you can insert a parenthesis at any position of the string. 8 | 9 | For example, if s = "()))", you can insert an opening parenthesis to be "(()))" or a closing parenthesis to be "())))". 10 | Return the minimum number of moves required to make s valid. 11 | */ 12 | class Solution { 13 | public: 14 | int minAddToMakeValid(string s) { 15 | stack st; 16 | int cnt = 0; 17 | for(int i = 0; i< s.length(); i++) 18 | { 19 | if(s[i]=='('){ 20 | // For open brace push it on stack 21 | st.push(s[i]); 22 | } 23 | else 24 | { 25 | // Else close brace has found 26 | if(!st.empty()) 27 | { 28 | // If stack is not empty means this close brace has an open brace previously 29 | st.pop(); 30 | } 31 | else{ 32 | // this close brace does not have an open brace previously 33 | cnt++; 34 | } 35 | } 36 | } 37 | if(st.empty()){ 38 | //string is balaced 39 | return cnt; 40 | } 41 | else{ 42 | return cnt + st.size(); 43 | } 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /Stack/pushAtBottom.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Approach : Recursive solution 3 | 4 | Base case : 5 | 1. Initially count will be 0 6 | 2. If count == stack.size() push(element) in answer stack ans return 7 | 8 | Step 1: Remove the top element of stack and store it somewhere 9 | 10 | Recursive call : 11 | With recursion go till the bottom of stack 12 | And as soon as bottom is reached with the base case push(element) to the bottom of stack. 13 | 14 | Processing : 15 | While returning back from recursion store the removed top element in answer stack again. 16 | */ 17 | 18 | stack solve(stack& ans,stack& myStack,int size, int x,int count = 0){ 19 | //Base case 20 | if(count == size){ 21 | ans.push(x); 22 | return ans; 23 | } 24 | //Otherwise 25 | //Step 1 26 | int topElement = myStack.top(); 27 | myStack.pop(); 28 | //Recursive call 29 | solve(ans,myStack,size,x,count+1); 30 | 31 | // While Returning back store the top element in ans 32 | ans.push(topElement); 33 | //Return the answer 34 | return ans; 35 | } 36 | stack pushAtBottom(stack& myStack, int x) 37 | { 38 | stack ans; 39 | return solve(ans,myStack,myStack.size(),x); 40 | } 41 | -------------------------------------------------------------------------------- /Stack/reverseStack.cpp: -------------------------------------------------------------------------------- 1 | void pushAtBottom(stack &stack,int x){ 2 | //If stack is empty push the element in stack 3 | if(stack.empty()){ 4 | stack.push(x); 5 | return; 6 | } 7 | // Remove and store the top elemement from stack 8 | int topElement = stack.top(); 9 | stack.pop(); 10 | // Call insert at bottom and go till the end of stack 11 | pushAtBottom(stack,x); 12 | 13 | // While coming back push the removed top element back in stack 14 | stack.push(topElement); 15 | } 16 | void reverseStack(stack &stack) { 17 | //Base Case 18 | if(stack.empty()){ 19 | return; 20 | } 21 | // Remove and store the top elemement from stack 22 | int top = stack.top(); 23 | stack.pop(); 24 | 25 | //Ask recursion to reverse the stack 26 | reverseStack(stack); 27 | 28 | // Once recursion has reversed the stack push top element at the bottom of stack 29 | pushAtBottom(stack,top); 30 | } 31 | -------------------------------------------------------------------------------- /Stack/sortStack.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | You're given a stack consisting of 'N' integers. Your task is to sort this stack in descending 3 | order using recursion. 4 | */ 5 | 6 | void insert_in_sorted_way(stack &stack , int element){ 7 | //Base case 8 | if(stack.empty() || stack.top() <= element){ //This condition will determine if the stack will get sorted in ascending or descending order 9 | stack.push(element); 10 | return; 11 | } 12 | 13 | // Remove and store top 14 | int top_element = stack.top(); 15 | stack.pop(); 16 | 17 | // Go inside the stack 18 | insert_in_sorted_way(stack ,element); 19 | 20 | // While returning push top_element back in stack 21 | stack.push(top_element); 22 | } 23 | void sortStack(stack &stack){ 24 | // Base case 25 | if(stack.empty()){ 26 | return; 27 | } 28 | // Remove and store top 29 | int top_element = stack.top(); 30 | stack.pop(); 31 | 32 | // Go inside stack 33 | sortStack(stack); 34 | 35 | // While returning push the top_element in sorted way 36 | insert_in_sorted_way(stack,top_element); 37 | } 38 | -------------------------------------------------------------------------------- /Stack/stack-inCPP-STL.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std ; 3 | int main() 4 | { 5 | //Creation of stack 6 | stack s; 7 | 8 | // Push operation 9 | s.push(10); 10 | s.push(20); 11 | 12 | // Pop operation 13 | s.pop(); 14 | 15 | //Peek element 16 | cout<<"Top element of stack is: "<top1 = -1; 12 | this->top2 = s; 13 | this->arr = new int[s]; 14 | this->size = s; 15 | } 16 | 17 | // Push in stack 1. 18 | void push1(int num) { 19 | //Check if there is at least one space left in stack; 20 | if((top2 - top1) >1){ 21 | top1++; 22 | arr[top1] = num; 23 | } 24 | else{ 25 | //Stack overflow 26 | } 27 | } 28 | 29 | // Push in stack 2. 30 | void push2(int num) { 31 | if((top2 - top1) >1){ 32 | top2--; 33 | arr[top2] = num; 34 | } 35 | else{ 36 | //Stack overflow 37 | } 38 | } 39 | 40 | // Pop from stack 1 and return popped element. 41 | int pop1() { 42 | if(top1 > -1){ 43 | int ans = arr[top1]; 44 | top1--; 45 | return ans; 46 | } 47 | else{ 48 | //Underflow 49 | return -1; 50 | } 51 | } 52 | 53 | // Pop from stack 2 and return popped element. 54 | int pop2() { 55 | if(top2 < size){ 56 | int ans = arr[top2]; 57 | top2++; 58 | return ans; 59 | } 60 | else{ 61 | //Underflow 62 | return -1; 63 | } 64 | } 65 | }; 66 | -------------------------------------------------------------------------------- /String/ComputingLPS.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std ; 3 | void __init__LPS(vector& LPS, string& s){ 4 | // Length of current LPS is 0 5 | int len = 0; 6 | // LPS for 0th char is always 0 7 | LPS[0] = 0; 8 | int i = 1; 9 | while(i < LPS.size()){ 10 | if(s[i] == s[len]){ 11 | // We can get suffix = prefix 12 | len++; 13 | LPS[i] = len; 14 | i++; 15 | } 16 | else{ 17 | if(len == 0){ 18 | LPS[i] = 0; 19 | i++; 20 | } 21 | else{ 22 | len = LPS[len - 1]; 23 | } 24 | } 25 | } 26 | } 27 | int main() 28 | { 29 | string s = "aaaabbbaaaa"; 30 | vectorLPS(s.length(), 0); 31 | __init__LPS(LPS, s); 32 | for(int i = 0 ; i < LPS.size();i++){ 33 | cout<& v){ 4 | if(root == NULL){ 5 | return; 6 | } 7 | inorder(root->left,v); 8 | v.push_back(root->val); 9 | inorder(root->right,v); 10 | } 11 | public: 12 | bool findTarget(TreeNode* root, int target) { 13 | ios_base::sync_with_stdio(0); 14 | cin.tie(0); 15 | vector v; 16 | inorder(root,v); 17 | int i = 0; 18 | int j = v.size()-1; 19 | while(i target){ 31 | j--; 32 | } 33 | } 34 | // WE'RE OUT OF LOOP MEANS NO VALUES FOUND 35 | return false; 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /Tree/BST/LCA-in-BST.cpp: -------------------------------------------------------------------------------- 1 | //RECURSIVE 2 | class Solution { 3 | private: 4 | TreeNode* solve (TreeNode* root, TreeNode* a, TreeNode* b){ 5 | if(root == NULL){ 6 | return NULL; 7 | } 8 | if(root->val < a->val && root->val < b->val){ 9 | return solve(root->right, a,b); 10 | } 11 | if(root->val > a->val && root->val > b->val){ 12 | return solve(root->left, a,b); 13 | } 14 | return root; 15 | } 16 | public: 17 | TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { 18 | return solve(root,p,q); 19 | } 20 | }; 21 | 22 | //ITERATIVE 23 | class Solution { 24 | public: 25 | TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* a, TreeNode* b) { 26 | ios_base::sync_with_stdio(false); 27 | cin.tie(NULL); 28 | while(root!=NULL) 29 | { 30 | if(root->val < a->val && root->val < b->val){ 31 | root = root->right; 32 | } 33 | else if(root->val > a->val && root->val > b->val){ 34 | root = root->left; 35 | } 36 | else{ 37 | // If root found break and come out 38 | break; 39 | } 40 | } 41 | return root; 42 | } 43 | }; 44 | 45 | 46 | // TC O(N) 47 | -------------------------------------------------------------------------------- /Tree/BST/balanceBST.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | 13 | // CONSTRUCT INORDERED SORTED ARRAY 14 | // USE A. Convert Sorted Array to Binary Search Tree LOGIC TO SOLVE 15 | class Solution { 16 | private: 17 | void inorder(TreeNode* root, vector& v){ 18 | if(root == NULL){ 19 | return; 20 | } 21 | inorder(root->left,v); 22 | v.push_back(root->val); 23 | inorder(root->right,v); 24 | } 25 | 26 | // A. LOGIC 27 | TreeNode* solve(int s, int e, vector& v){ 28 | if(s > e){ 29 | return NULL; 30 | } 31 | int m = (s + e)/2; 32 | TreeNode* root = new TreeNode(v[m]); 33 | root -> left = solve(s,m-1,v); 34 | root-> right = solve(m+1,e,v); 35 | return root; 36 | } 37 | public: 38 | TreeNode* balanceBST(TreeNode* root) { 39 | ios_base::sync_with_stdio(0); 40 | cin.tie(0); 41 | vector v; 42 | inorder(root,v); 43 | 44 | // A. LOGIC 45 | int s = 0; 46 | int e = v.size()-1; 47 | TreeNode* ans = solve(s,e,v); 48 | return ans; 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /Tree/BST/bstFromPreorder.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | TreeNode* solve(vector& pre, int mini,int maxi, int& i){ 4 | if(i >= pre.size()){ 5 | return NULL; 6 | } 7 | if(pre[i]maxi){ 8 | return NULL; 9 | } 10 | TreeNode* root = new TreeNode(pre[i++]); 11 | root->left = solve(pre,mini,root->val,i); 12 | root->right = solve(pre,root->val,maxi,i); 13 | return root; 14 | } 15 | public: 16 | TreeNode* bstFromPreorder(vector& pre) { 17 | int mini = INT_MIN; 18 | int maxi = INT_MAX; 19 | int i = 0; 20 | return solve(pre, mini, maxi,i); 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /Tree/BST/convertBST-to-GreaterTree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | class Solution { 13 | private: 14 | void solve(TreeNode*& root, int &sum){ 15 | // If root is NULL return 16 | if(root == NULL){ 17 | return; 18 | } 19 | // Go to extream right as this value will be the largest 20 | solve(root->right, sum); 21 | // Add root->data to sum 22 | sum = sum + root->val; 23 | // Replace root->data with sum 24 | root->val = sum; 25 | // Go to left 26 | solve(root->left,sum); 27 | } 28 | public: 29 | TreeNode* convertBST(TreeNode* root) { 30 | // Initialize sum with 0 31 | int sum = 0; 32 | // Call solve 33 | solve(root, sum); 34 | return root; 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /Tree/BST/create-BST.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std ; 3 | class TreeNode{ 4 | public: 5 | int data; 6 | TreeNode* left; 7 | TreeNode*right; 8 | TreeNode(int data){ 9 | this->data = data; 10 | this->left = NULL; 11 | this->right =NULL; 12 | } 13 | }; 14 | 15 | 16 | void inorder(TreeNode *root) 17 | { 18 | if (root->data == -1) 19 | { 20 | return; 21 | } 22 | if(root->left) 23 | inorder(root->left); 24 | cout << root->data << " "; 25 | if(root->right) 26 | inorder(root->right); 27 | } 28 | TreeNode* insertIntoBST(TreeNode*& root,int data){ 29 | // Base case 30 | if(root == NULL){ 31 | root = new TreeNode(data); 32 | return root; 33 | } 34 | // Data greater than root 35 | if(data > root->data){ 36 | root->right = insertIntoBST(root->right,data); 37 | } 38 | else{ 39 | // Data smaller than root 40 | root->left = insertIntoBST(root->left,data); 41 | } 42 | return root; 43 | } 44 | void takeData(TreeNode*& root){ 45 | int data; 46 | cin>>data; 47 | while(data != -1){ 48 | insertIntoBST(root,data); 49 | cin>>data; 50 | } 51 | } 52 | int main() 53 | { 54 | TreeNode* root = NULL; 55 | cout<<"Enter data to build BST: "; 56 | takeData(root); 57 | cout<<"TREE Inorder: "; 58 | inorder(root); 59 | return 0; 60 | } -------------------------------------------------------------------------------- /Tree/BST/kthSmallest_BST.cpp: -------------------------------------------------------------------------------- 1 | //APPROACH 1: 2 | /* 3 | INORDER OF BST IS ALWAYS SORTED 4 | */ 5 | class Solution { 6 | private: 7 | void inorder(TreeNode* root,vector& v){ 8 | if(root == NULL){ 9 | return ; 10 | } 11 | inorder(root->left, v); 12 | v.push_back(root->val); 13 | inorder(root->right ,v); 14 | } 15 | public: 16 | int kthSmallest(TreeNode* root, int k) { 17 | vector v; 18 | inorder(root, v); 19 | return v[k-1]; 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /Tree/BST/minValueInBST.cpp: -------------------------------------------------------------------------------- 1 | // Function to find the minimum element in the given BST. 2 | int minValue(Node* root) { 3 | if(root == NULL){ 4 | return -1; 5 | } 6 | Node* temp = root; 7 | while(temp->left != NULL) 8 | { 9 | temp = temp->left; 10 | } 11 | return temp->data; 12 | } 13 | -------------------------------------------------------------------------------- /Tree/BST/search-In-BST.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | TreeNode* searchBST(TreeNode* root, int val) { 15 | // Base case 16 | if(root != NULL){ 17 | if(root->val == val){ 18 | return root; 19 | } 20 | // recursive Calls 21 | else if(val < root->val){ 22 | return searchBST(root->left,val); 23 | } 24 | else{ 25 | return searchBST(root->right,val); 26 | } 27 | } 28 | else{ 29 | return NULL; 30 | } 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /Tree/BST/sortedArrayToBST.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | class Solution 13 | { 14 | private: 15 | TreeNode* solve(int s, int e, vector v){ 16 | if(s > e){ 17 | return NULL; 18 | } 19 | int m = (s + e)/2; 20 | TreeNode* root = new TreeNode(v[m]); 21 | root -> left = solve(s,m-1,v); 22 | root-> right = solve(m+1,e,v); 23 | return root; 24 | } 25 | public: 26 | TreeNode *sortedArrayToBST(vector &v) 27 | { 28 | int s = 0; 29 | int e = v.size()-1; 30 | TreeNode* ans = solve(s,e,v); 31 | return ans; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /Tree/BST/sortedListToBST.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | 4 | public: 5 | TreeNode* sortedListToBST(ListNode* head) { 6 | // No list 7 | if(head == NULL){ 8 | return NULL; 9 | } 10 | // Single node 11 | if(head->next == NULL){ 12 | return (new TreeNode(head->val)); 13 | } 14 | 15 | // find mid of list 16 | ListNode* slow = head; 17 | ListNode* fast = head; 18 | ListNode* mid = NULL; 19 | 20 | while(fast != NULL && fast->next != NULL){ 21 | mid = slow; 22 | slow = slow -> next; 23 | fast = fast->next ->next; 24 | } 25 | 26 | TreeNode* root = new TreeNode(slow->val); 27 | mid->next = NULL; 28 | 29 | // Recursive call 30 | root->left = sortedListToBST(head); 31 | root->right = sortedListToBST(slow->next); 32 | 33 | return root; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /Tree/Heap/Check-Completeness-of-BinaryTree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | class Solution { 13 | private: 14 | int countNodes(TreeNode* root){ 15 | // Base case 16 | if(root == NULL){ 17 | return 0; 18 | } 19 | // Root + Left + Right 20 | int ans = 1 + countNodes(root->left) + countNodes(root->right); 21 | return ans; 22 | } 23 | bool solve(TreeNode* root, int index, int nodeCount){ 24 | // Base case 25 | if(root == NULL){ 26 | return true; 27 | } 28 | 29 | // If index exceeds total count 30 | if(index >= nodeCount){ 31 | return false; 32 | } 33 | 34 | // Else solve left and right subtree 35 | else{ 36 | bool leftAns= solve(root->left, 2*index+1 ,nodeCount); 37 | bool rightAns= solve(root->right, 2*index+2 ,nodeCount); 38 | return leftAns && rightAns; 39 | } 40 | } 41 | public: 42 | bool isCompleteTree(TreeNode* root) { 43 | int nodeCount = countNodes(root); 44 | int index = 0; 45 | return solve(root, index, nodeCount); 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /Tree/Heap/Convert-BST-to-MinHeap.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | /************************************************************* 3 | 4 | Following is the Binary Tree node structure: 5 | 6 | class BinaryTreeNode { 7 | 8 | public : 9 | int data; 10 | BinaryTreeNode* left; 11 | BinaryTreeNode* right; 12 | 13 | BinaryTreeNode(int data) { 14 | this -> left = NULL; 15 | this -> right = NULL; 16 | this -> data = data; 17 | } 18 | }; 19 | 20 | *************************************************************/ 21 | void inorder(BinaryTreeNode* root,vector& arr ){ 22 | if(root == NULL){ 23 | return; 24 | } 25 | inorder(root->left, arr); 26 | arr.push_back(root->data); 27 | inorder(root->right, arr); 28 | } 29 | void buildTree(BinaryTreeNode*& root, vector& arr, int& s) 30 | { 31 | if(root == NULL){ 32 | return; 33 | } 34 | root->data = arr[s++]; 35 | buildTree(root->left, arr, s); 36 | buildTree(root->right, arr, s); 37 | } 38 | BinaryTreeNode* convertBST(BinaryTreeNode* root) 39 | { 40 | // Store BST TO inorder 41 | vector arr; 42 | inorder(root, arr); 43 | int s = 0; 44 | // Build tree from inorder 45 | buildTree(root, arr, s); 46 | return root; 47 | } 48 | -------------------------------------------------------------------------------- /Tree/Heap/Kth_Largest_smallest_in_array.cpp: -------------------------------------------------------------------------------- 1 | // Kth largest 2 | class Solution { 3 | public: 4 | int findKthLargest(vector& nums, int k) { 5 | priority_queue, greater> pq; 6 | // Step 1: Build heap from first k elements 7 | for(int i = 0 ; i < k ; i++){ 8 | pq.push(nums[i]); 9 | } 10 | 11 | // Step 2: For remaining n -k elements 12 | for(int i = k ; i < nums.size() ; i++){ 13 | if(nums[i] > pq.top()){ 14 | pq.pop(); 15 | pq.push(nums[i]); 16 | } 17 | } 18 | 19 | // Step 3: Your answer will be top of heap 20 | int ans = pq.top(); 21 | return ans; 22 | } 23 | }; 24 | 25 | 26 | 27 | 28 | // Kth smallest 29 | class Solution { 30 | public: 31 | int findKthSmallest(vector& nums, int k) { 32 | priority_queue pq; 33 | // Step 1: Build heap from first k elements 34 | for(int i = 0 ; i < k ; i++){ 35 | pq.push(nums[i]); 36 | } 37 | 38 | // Step 2: For remaining n -k elements 39 | for(int i = k ; i < nums.size() ; i++){ 40 | if(nums[i] < pq.top()){ 41 | pq.pop(); 42 | pq.push(nums[i]); 43 | } 44 | } 45 | 46 | // Step 3: Your answer will be top of heap 47 | int ans = pq.top(); 48 | return ans; 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /Tree/Heap/PriorityQueue(Using STL).c: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std ; 3 | int main() 4 | { 5 | // USING CPP STL 6 | // MAX HEAP BY DEFAULT 7 | priority_queue pq; 8 | pq.push(4); 9 | pq.push(2); 10 | pq.push(5); 11 | pq.push(3); 12 | 13 | cout<<"\nElement at top : "<, greater > pq2; 19 | pq2.push(4); 20 | pq2.push(2); 21 | pq2.push(5); 22 | pq2.push(3); 23 | 24 | cout<<"\nElement at top : "< e1, pair e2) { 4 | if(e1.first > e2.first){ 5 | return true; 6 | } 7 | if(e1.first == e2.first){ 8 | if(e1.second >= e2.second){ 9 | return true; 10 | } 11 | } 12 | return false; 13 | } 14 | }; 15 | // min heap 16 | priority_queue, vector>, MyComparator> minHeap; 17 | -------------------------------------------------------------------------------- /Tree/Heap/getKthLargest.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | // Logic 1: TC => O(n sq) 3 | // SC => O(n sq) 4 | int getKthLargest(vector &arr, int k) 5 | { 6 | // To store all sub array ans use vector 7 | vector ans; 8 | // Looping 9 | for(int i = 0 ; i < arr.size(); i++){ 10 | int sum = 0 ; 11 | for(int j = i ; j < arr.size() ; j++){ 12 | sum += arr[j]; 13 | ans.push_back(sum); 14 | } 15 | } 16 | // Sorting the final ans to get kth largest 17 | sort(ans.begin(), ans.end()); 18 | int n = ans.size(); 19 | return ans[n-k]; 20 | } 21 | 22 | 23 | 24 | #include 25 | // Logic 2: TC => O(n sq) 26 | // SC => O(k) 27 | int getKthLargest(vector &arr, int k) 28 | { 29 | // To store all sub array ans use heap 30 | priority_queue, greater> min_heap; 31 | // Looping 32 | for(int i = 0 ; i < arr.size(); i++){ 33 | int sum = 0 ; 34 | for(int j = i ; j < arr.size() ; j++){ 35 | sum += arr[j]; 36 | if(min_heap.size() < k){ 37 | min_heap.push(sum); 38 | } 39 | else{ 40 | if(sum > min_heap.top()){ 41 | min_heap.pop(); 42 | min_heap.push(sum); 43 | } 44 | } 45 | } 46 | } 47 | return min_heap.top(); 48 | } 49 | -------------------------------------------------------------------------------- /Tree/Heap/heapSort.cpp: -------------------------------------------------------------------------------- 1 | void heapify(int *arr, int n, int i){ 2 | // Take current find its right and left child 3 | int current = i; 4 | int left = 2*i; 5 | int right = 2*i+1; 6 | 7 | // If small found then swap 8 | if(left <= n && arr[current] < arr[left]){ 9 | current = left; 10 | } 11 | 12 | if(right <= n && arr[current] < arr[right]){ 13 | current = right; 14 | } 15 | 16 | // if current got updated then check again for bottom subtree 17 | if( current != i){ 18 | swap(arr[current], arr[i]); 19 | heapify(arr,n,current); 20 | } 21 | } 22 | 23 | void heapSort(int *arr, int n){ 24 | int size = n ; 25 | while(size > 1){ 26 | //Step 1 : Swap last element with fist 27 | swap(arr[size], arr[1]); 28 | 29 | // Step 2: 30 | size--; 31 | 32 | // Step 3: heapify 33 | heapify(arr, size, 1); 34 | } 35 | } 36 | int main() 37 | { 38 | int arr[6] = {-1,54,53,55,52,50}; 39 | 40 | // Heap creation 41 | int n = 5; 42 | for(int i = n / 2 ; i > 0 ;i-- ){ 43 | heapify(arr, n, i); 44 | } 45 | for(int i = 1 ; i <= n ;i++) 46 | { 47 | cout< 2 | using namespace std; 3 | void heapify(vector &arr, int size, int index) 4 | { 5 | int current = index; 6 | int leftChild = index * 2 + 1; 7 | int rightChild = index * 2 + 2; 8 | 9 | // Check if current is smaller than left child 10 | if (leftChild < size && arr[current] < arr[leftChild]) 11 | { 12 | current = leftChild; 13 | } 14 | 15 | // Check if current is smaller than right child 16 | if (rightChild < size && arr[current] < arr[rightChild]) 17 | { 18 | current = rightChild; 19 | } 20 | 21 | // If current is updated 22 | if (current != index) 23 | { 24 | swap(arr[current], arr[index]); 25 | heapify(arr, size, current); 26 | } 27 | } 28 | int main() 29 | { 30 | vector arr ; 31 | arr.push_back(59); 32 | arr.push_back(54); 33 | arr.push_back(53); 34 | arr.push_back(55); 35 | arr.push_back(52); 36 | arr.push_back(50); 37 | int n = 6; 38 | for (int i = n / 2 -1 ; i >= 0; i--) 39 | { 40 | heapify(arr, n, i); 41 | } 42 | for (int i = 0; i < n; i++) 43 | { 44 | cout << arr[i] << ' '; 45 | } 46 | cout << endl; 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /Tree/Invert-Binary-Tree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | class Solution { 13 | private: 14 | void solve(TreeNode*& root){ 15 | if(root == NULL){ 16 | return; 17 | } 18 | TreeNode* temp = root->left; 19 | root -> left = root->right; 20 | root -> right = temp; 21 | solve(root->right); 22 | solve(root->left); 23 | } 24 | public: 25 | TreeNode* invertTree(TreeNode* root) { 26 | solve(root); 27 | return root; 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /Tree/LowestCommonAncestor.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | TreeNode* solve(TreeNode* root, TreeNode* p, TreeNode* q){ 4 | // Empty tree 5 | if(root == NULL){ 6 | return root; 7 | } 8 | 9 | // Common Ansestor foiund 10 | if(root == p || root == q){ 11 | return root; 12 | } 13 | 14 | // Solve recursively left and right subtree 15 | TreeNode* leftTreeAns = solve(root->left, p,q); 16 | TreeNode* rightTreeAns = solve(root->right, p,q); 17 | 18 | // If both answers are NULL means NO solution 19 | if(leftTreeAns == NULL && rightTreeAns == NULL){ 20 | return NULL; 21 | } 22 | 23 | // if one of the ans is found then return that answer 24 | else if(leftTreeAns != NULL && rightTreeAns == NULL){ 25 | return leftTreeAns; 26 | } 27 | else if(leftTreeAns == NULL && rightTreeAns != NULL){ 28 | return rightTreeAns; 29 | } 30 | 31 | // Both answers are found at left and right of particular root so return that root as answer 32 | else{ 33 | return root; 34 | } 35 | } 36 | public: 37 | TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) 38 | { 39 | ios_base::sync_with_stdio(false); 40 | cin.tie(0); 41 | TreeNode* ans = solve(root, p, q); 42 | return ans; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /Tree/Morris-Inorder-Traversal.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | 13 | //Using Morris Traversal 14 | // TC: O(N) 15 | // SC: O(1) 16 | class Solution { 17 | private: 18 | TreeNode* findPredecessor(TreeNode* curr){ 19 | TreeNode* temp = curr->left; 20 | while(temp->right != NULL && temp->right != curr){ 21 | temp = temp->right; 22 | } 23 | return temp; 24 | } 25 | public: 26 | vector inorderTraversal(TreeNode* root) { 27 | vector ans; 28 | if(root == NULL) 29 | { 30 | return ans; 31 | } 32 | // Start Traversal 33 | TreeNode* curr = root; 34 | while(curr != NULL){ 35 | if(!curr->left){ 36 | ans.push_back(curr->val); 37 | curr = curr->right; 38 | } 39 | else{ 40 | TreeNode* predecessor = findPredecessor(curr); 41 | if(predecessor->right == NULL){ 42 | // Create link 43 | predecessor->right = curr; 44 | curr = curr->left; 45 | } 46 | else{ 47 | // Destroy link 48 | predecessor->right = NULL; 49 | ans.push_back(curr->val); 50 | curr = curr->right; 51 | } 52 | } 53 | } 54 | return ans; 55 | } 56 | }; 57 | -------------------------------------------------------------------------------- /Tree/No-Of-Leaf-Nodes.cpp: -------------------------------------------------------------------------------- 1 | /********************************************************** 2 | 3 | Following is the Binary Tree Node class structure: 4 | 5 | template 6 | class BinaryTreeNode { 7 | public : 8 | T data; 9 | BinaryTreeNode *left; 10 | BinaryTreeNode *right; 11 | 12 | BinaryTreeNode(T data) { 13 | this -> data = data; 14 | left = NULL; 15 | right = NULL; 16 | } 17 | }; 18 | 19 | ***********************************************************/ 20 | void solve(BinaryTreeNode *root, int& cnt){ 21 | if(root == NULL){ 22 | return; 23 | } 24 | // Check for leaf node 25 | if(root->left == NULL && root->right == NULL){ 26 | cnt++; 27 | } 28 | // Otherwise send left and right subtree to recursion and recursion will give ans 29 | solve(root->left,cnt); 30 | solve(root->right,cnt); 31 | } 32 | int noOfLeafNodes(BinaryTreeNode *root){ 33 | int cnt = 0; 34 | solve(root,cnt); 35 | return cnt; 36 | } 37 | -------------------------------------------------------------------------------- /Tree/bottomView.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector bottomView(Node *root) { 4 | vector ans; 5 | if(root == NULL){ 6 | return ans; 7 | } 8 | map mp; 9 | queue> q; 10 | q.push(make_pair(root,0)); 11 | while(!q.empty()){ 12 | pair temp = q.front(); 13 | q.pop(); 14 | 15 | Node* frontNode = temp.first; 16 | int horizontal_distance = temp.second; 17 | 18 | mp[horizontal_distance] = frontNode->data; 19 | 20 | if(frontNode -> left){ 21 | q.push(make_pair(frontNode -> left,horizontal_distance-1)); 22 | } 23 | if(frontNode -> right){ 24 | q.push(make_pair(frontNode -> right,horizontal_distance+1)); 25 | } 26 | } 27 | 28 | for(auto i : mp){ 29 | ans.push_back(i.second); 30 | } 31 | return ans; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /Tree/construct-TreeFrom-in_&_post.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | private: 3 | int find_Position(vector in, int element){ 4 | int n = in.size(); 5 | for(int i = 0 ; i< n ;i++){ 6 | if(in[i] == element){ 7 | return i; 8 | } 9 | } 10 | return -1; 11 | } 12 | TreeNode* solve(vectorpost , vector in, int& root_index , int start, int end, int size){ 13 | // Base case 14 | if(root_index < 0 || start > end){ 15 | return NULL; 16 | } 17 | // Find root element from preorder traversal 18 | int element = post[root_index--]; 19 | TreeNode* root = new TreeNode(element); 20 | 21 | // Find root element's position from inorder traversal 22 | int position = find_Position(in, element); 23 | 24 | // Call for left subtree and right subtree 25 | root->right = solve(post, in, root_index, position+1, end, size); 26 | root->left = solve(post, in, root_index, start, position-1,size); 27 | 28 | return root; 29 | } 30 | public: 31 | TreeNode* buildTree(vector& in, vector& post) 32 | { 33 | int post_size = post.size(); 34 | int in_size = in.size(); 35 | int root_index = post_size-1; 36 | int in_start = 0; 37 | int in_end = in_size-1; 38 | TreeNode* root = solve(post, in, root_index, in_start, in_end, post_size); 39 | return root; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /Tree/countNodesIn-CBST.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | class Solution { 13 | private: 14 | int solve(TreeNode* root, int& ans){ 15 | if(root == NULL){ 16 | return 0; 17 | } 18 | ans = ans + 1; 19 | solve(root->left, ans); 20 | solve(root->right, ans); 21 | return ans; 22 | } 23 | public: 24 | int countNodes(TreeNode* root) { 25 | int ans=0; 26 | return solve(root, ans); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /Tree/diagonalTraversal.cpp: -------------------------------------------------------------------------------- 1 | /* A binary tree node 2 | struct Node 3 | { 4 | int data; 5 | Node* left, * right; 6 | }; */ 7 | 8 | void diagonalTravel(Node * root, map>& mp, int lvl = 0){ 9 | if(root == NULL){ 10 | return; 11 | } 12 | 13 | diagonalTravel(root->right,mp,lvl); 14 | diagonalTravel(root->left,mp,lvl+1); 15 | mp[lvl].push_back(root->data); 16 | } 17 | vector diagonal(Node *root) 18 | { 19 | map> mp; 20 | vector> ans; 21 | vector res; 22 | diagonalTravel(root,mp); 23 | for(auto i:mp){ 24 | ans.push_back(i.second); 25 | } 26 | for(int i = 0 ; i< ans.size() ; i++){ 27 | for(int j = ans[i].size()-1 ; j>=0;j--){ 28 | res.push_back(ans[i][j]); 29 | } 30 | } 31 | return res; 32 | } 33 | 34 | 35 | 36 | 37 | // Approach 2 38 | /* A binary tree node 39 | struct Node 40 | { 41 | int data; 42 | Node* left, * right; 43 | }; */ 44 | 45 | 46 | vector diagonal(Node *root) 47 | { 48 | vector ans; 49 | if(root == NULL){ 50 | return ans; 51 | } 52 | queue q; 53 | q.push(root); 54 | 55 | while(!q.empty()){ 56 | Node* temp = q.front(); 57 | q.pop(); 58 | while(temp != NULL){ 59 | if(temp->left){ 60 | q.push(temp->left); 61 | } 62 | ans.push_back(temp->data); 63 | temp = temp->right; 64 | } 65 | } 66 | return ans; 67 | } 68 | -------------------------------------------------------------------------------- /Tree/findBottomLeftValue.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | GO WITH THE LEVEL ORDER AND THEN RETURN THE FIRST VALUE IN LAST LEVEL 3 | */ 4 | class Solution { 5 | public: 6 | int findBottomLeftValue(TreeNode* root) { 7 | int val = 0; 8 | queue q; 9 | q.push(root); 10 | q.push(NULL); 11 | while(!q.empty()){ 12 | TreeNode* temp = q.front(); 13 | q.pop(); 14 | if(temp != NULL){ 15 | val = temp->val; 16 | // We want the leftmost root so we will push right first then left 17 | if(temp->right){ 18 | q.push(temp->right); 19 | } 20 | if(temp->left){ 21 | q.push(temp->left); 22 | } 23 | } 24 | else{ 25 | // One level is complete 26 | if(!q.empty()){ 27 | q.push(NULL); 28 | } 29 | } 30 | } 31 | return val; 32 | } 33 | }; 34 | -------------------------------------------------------------------------------- /Tree/getMaxSum-of-Non-adjoint-Nodes.cpp: -------------------------------------------------------------------------------- 1 | //Node Structure 2 | /* 3 | struct Node 4 | { 5 | int data; 6 | Node* left; 7 | Node* right; 8 | }; 9 | */ 10 | 11 | class Solution{ 12 | private: 13 | pair solve(Node *root){ 14 | if(root == NULL){ 15 | pair p = make_pair(0,0); 16 | return p; 17 | } 18 | 19 | pair leftSum = solve(root->left); 20 | pair rightSum = solve(root->right); 21 | 22 | pair ans; 23 | //ans.first will contain the maxsum including current node 24 | ans.first = root->data + leftSum.second + rightSum.second; 25 | //ans.second will contain the massum excluding current node 26 | ans.second = max(leftSum.first, leftSum.second) 27 | + max(rightSum.first , rightSum.second); 28 | return ans; 29 | } 30 | public: 31 | //Function to return the maximum sum of non-adjacent nodes. 32 | int getMaxSum(Node *root) 33 | { 34 | //This pair will contain 35 | // first -> the sum obtained by including current nodes data , 36 | // second -> the sum obtained by excluding current nodes data 37 | pair ans = solve(root); 38 | 39 | return max(ans.first, ans.second); 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /Tree/goodNodes.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | class Solution { 13 | private: 14 | void solve(TreeNode* root,int max, int &cnt){ 15 | if(root == NULL){ 16 | return; 17 | } 18 | // initially keep max veriable and then update it as you move down the path 19 | if(root->val >= max){ 20 | cnt++; 21 | max = root->val; 22 | } 23 | solve(root->left,max,cnt); 24 | solve(root->right,max,cnt); 25 | } 26 | public: 27 | int goodNodes(TreeNode* root) { 28 | ios_base::sync_with_stdio(0); 29 | cin.tie(0); 30 | int max = INT_MIN; 31 | int count = 0; 32 | solve(root,max,count); 33 | return count; 34 | } 35 | }; 36 | -------------------------------------------------------------------------------- /Tree/isLeafSimilar.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | class Solution { 13 | private: 14 | void findLeaf(TreeNode* root, vector &v){ 15 | // Empty tree 16 | if(root == NULL){ 17 | return; 18 | } 19 | // Leaf node 20 | if(root->left == NULL && root->right == NULL){ 21 | v.push_back(root->val); 22 | return; 23 | } 24 | // Recursive call 25 | findLeaf(root->left,v); 26 | findLeaf(root->right,v); 27 | } 28 | public: 29 | bool leafSimilar(TreeNode* root1, TreeNode* root2) { 30 | // Find all leaf nodes and store in vectors and then check if vectors are same 31 | ios_base::sync_with_stdio(0); 32 | cin.tie(0); 33 | vector tree1; 34 | vector tree2; 35 | findLeaf(root1, tree1); 36 | findLeaf(root2, tree2); 37 | if(tree1.size() != tree2.size()){ 38 | return false; 39 | } 40 | for(int i = 0 ; i isSumTreeFast(Node* root){ 14 | if(root == NULL){ 15 | // empty tree 16 | pair p = make_pair(true, 0); 17 | return p; 18 | } 19 | if((root->left == NULL && root->right ==NULL)){ 20 | // leaf node 21 | pair p = make_pair(true, root->data); 22 | return p; 23 | } 24 | // solve left and right subtree 25 | pair left = isSumTreeFast(root->left); 26 | pair right = isSumTreeFast(root->right); 27 | 28 | 29 | bool left_tree = left.first; 30 | bool right_tree = right.first; 31 | bool sum = left.second + right.second == root->data; 32 | 33 | pairans; 34 | 35 | // Check for subtree 36 | if(left_tree, right_tree, sum){ 37 | ans.first = true; 38 | ans.second = left.second + right.second+ root->data; 39 | } 40 | else{ 41 | ans.first = false; 42 | } 43 | return ans; 44 | } 45 | public: 46 | bool isSumTree(Node* root) 47 | { 48 | pairans; 49 | ans = isSumTreeFast(root); 50 | return ans.first; 51 | } 52 | }; 53 | -------------------------------------------------------------------------------- /Tree/kthAncestor.cpp: -------------------------------------------------------------------------------- 1 | //User function Template for C++ 2 | /* 3 | Structure of the node of the binary tree is as 4 | struct Node 5 | { 6 | int data; 7 | struct Node *left, *right; 8 | }; 9 | */ 10 | // your task is to complete this function 11 | Node* solve(Node *root, int& k, int node){ 12 | //Base case 13 | if(root == NULL){ 14 | return root; 15 | } 16 | 17 | // If root data and node value are equal 18 | if(root->data == node){ 19 | return root; 20 | } 21 | 22 | Node* leftAns = solve(root->left, k, node); 23 | Node* rightAns = solve(root->right, k, node); 24 | 25 | if(leftAns != NULL && rightAns == NULL){ 26 | k--; 27 | if(k<=0){ 28 | //lock the answer 29 | k = INT_MAX; 30 | return root; 31 | } 32 | return leftAns; 33 | } 34 | 35 | if(leftAns == NULL && rightAns != NULL){ 36 | k--; 37 | if(k<=0){ 38 | //lock the answer 39 | k = INT_MAX; 40 | return root; 41 | } 42 | return rightAns; 43 | } 44 | return NULL; 45 | } 46 | int kthAncestor(Node *root, int k, int node) 47 | { 48 | Node* ans = solve(root, k,node); 49 | if(ans == NULL || ans->data == node){ 50 | return -1; 51 | } 52 | else{ 53 | return ans->data; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Tree/leftView.cpp: -------------------------------------------------------------------------------- 1 | vector leftView(Node *root) 2 | { 3 | vector ans; 4 | if(root == NULL){ 5 | return ans; 6 | } 7 | mapmp; 8 | queue>q; // This queue will hold Node and level 9 | q.push(make_pair(root,0)); 10 | while(!q.empty()){ 11 | pair temp = q.front(); 12 | q.pop(); 13 | 14 | Node* frontNode = temp.first; 15 | int lvl = temp.second; 16 | 17 | if(mp.find(lvl) == mp.end()){ 18 | mp[lvl] = frontNode->data; 19 | } 20 | 21 | if(frontNode->left){ 22 | q.push(make_pair(frontNode->left,lvl+1)); 23 | } 24 | if(frontNode->right){ 25 | q.push(make_pair(frontNode->right,lvl+1)); 26 | } 27 | } 28 | for(auto i : mp){ 29 | ans.push_back(i.second); 30 | } 31 | return ans; 32 | } 33 | -------------------------------------------------------------------------------- /Tree/maximumHeight.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | 13 | // 3 line Solution: 14 | class Solution { 15 | public: 16 | int maxDepth(TreeNode* root) { 17 | if(root == NULL) return 0; 18 | return max(maxDepth(root->left) ,maxDepth(root->right))+1; 19 | } 20 | }; 21 | 22 | // Code for better understanding 23 | class Solution { 24 | public: 25 | int maxDepth(TreeNode* root) { 26 | // Base Case 27 | if(root == NULL){ 28 | // If no node in tree return 0 as height 29 | return 0; 30 | } 31 | // Recursion will find max depth of left subtree 32 | int max_depth_left = maxDepth(root->left); 33 | 34 | // Recursion will find max depth of right subtree 35 | int max_depth_right = maxDepth(root->right); 36 | 37 | // Our job is to add root to max height 38 | int max_depth = max(max_depth_left, max_depth_right); 39 | int ans = max_depth + 1; 40 | 41 | return ans; 42 | } 43 | }; 44 | -------------------------------------------------------------------------------- /Tree/merge-two-Btrees.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) { 15 | // BASE CASES 16 | if(root1 == NULL && root2 == NULL){ 17 | return NULL; 18 | } 19 | if(root1 != NULL && root2 == NULL){ 20 | return root1; 21 | } 22 | if(root1 == NULL && root2 != NULL){ 23 | return root2; 24 | } 25 | // else both non null 26 | TreeNode* newNode = new TreeNode(root1->val + root2->val); 27 | newNode->left = mergeTrees(root1->left, root2->left); 28 | newNode->right = mergeTrees(root1->right, root2->right); 29 | return newNode; 30 | } 31 | }; 32 | -------------------------------------------------------------------------------- /Tree/minimumHeight.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | int minDepth(TreeNode* root) { 15 | if(root == NULL){ 16 | return 0; 17 | } 18 | // If tree has no left child return height of right sub tree +1 19 | if(root->left == NULL) 20 | { 21 | return minDepth(root->right)+1; 22 | } 23 | // If tree has no right child return height of left sub tree +1 24 | if(root->right == NULL) 25 | { 26 | return minDepth(root->left)+1; 27 | } 28 | // Recursion will give you minimum height of left subtree 29 | int left_min = minDepth(root->left); 30 | 31 | // Recursion will give you minimum height of right subtree 32 | int right_min = minDepth(root->right); 33 | 34 | // find minimum from right_min and left_min 35 | int min_depth = min(left_min, right_min); 36 | 37 | // Add height of root to min height 38 | int ans = min_depth+1; 39 | return ans; 40 | } 41 | }; 42 | -------------------------------------------------------------------------------- /Tree/pathSumTarget.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | class Solution { 13 | private: 14 | void solve(TreeNode* root, vector v, int target, int& count){ 15 | // Base case 16 | if(root == NULL){ 17 | return ; 18 | } 19 | 20 | // Store current root value in vector 21 | v.push_back(root->val); 22 | 23 | // Solve left subtree and solve right subtree 24 | solve(root->left, v, target, count); 25 | solve(root->right, v, target, count); 26 | 27 | // Check sum 28 | long long sum = 0; 29 | for(int i = v.size()-1 ; i>= 0 ;i--){ 30 | sum += v[i]; 31 | if(sum == target){ 32 | count++; 33 | } 34 | } 35 | 36 | // While going pack remove the last stored data from vector 37 | v.pop_back(); 38 | } 39 | public: 40 | int pathSum(TreeNode* root, int target) { 41 | ios_base::sync_with_stdio(0); 42 | cin.tie(0); 43 | vector v; 44 | int count = 0; 45 | solve(root, v, target,count); 46 | return count; 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /Tree/removeLeafNodes-With-TargetVal.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | class Solution { 13 | private: 14 | TreeNode* solve(TreeNode* root, int t){ 15 | if(root == NULL){ 16 | return NULL; 17 | } 18 | // GO TO LEFT 19 | root -> left = solve(root->left,t); 20 | // GO TO RIGHT 21 | root ->right = solve(root->right,t); 22 | 23 | // IF FOUND LEAF AND VALUE MATCHES DELETE 24 | if(root->left == NULL && root->right == NULL && root->val ==t){ 25 | return NULL; 26 | } 27 | 28 | return root; 29 | } 30 | public: 31 | TreeNode* removeLeafNodes(TreeNode* root, int target) { 32 | ios_base::sync_with_stdio(0); 33 | cin.tie(0); 34 | return solve(root, target); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /Tree/sameTree.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode() : val(0), left(nullptr), right(nullptr) {} 8 | * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 9 | * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} 10 | * }; 11 | */ 12 | class Solution { 13 | public: 14 | bool isSameTree(TreeNode* p, TreeNode* q) { 15 | // No nodes in both trees 16 | if(p == NULL && q == NULL){ 17 | return true; 18 | } 19 | // One tree has node but other doesn't 20 | if(p == NULL && q != NULL){ 21 | return false; 22 | } 23 | if(p != NULL && q == NULL){ 24 | return false; 25 | } 26 | 27 | // Go in left and right subtree 28 | bool left = isSameTree(p->left , q->left); 29 | bool right = isSameTree(p->right , q->right); 30 | 31 | // Check if data is same 32 | bool data = p->val==q->val ? true : false; 33 | 34 | // if all part are true ans is true; 35 | if(left == true && right == true && data == true){ 36 | return true; 37 | } 38 | else{ 39 | return false; 40 | } 41 | } 42 | }; 43 | -------------------------------------------------------------------------------- /Tree/sumOfLongRootToLeafPath.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | structure of the node of the binary tree is as 3 | struct Node 4 | { 5 | int data; 6 | struct Node *left; 7 | struct Node *right; 8 | 9 | Node(int x) 10 | { 11 | data = x; 12 | left = NULL; 13 | right = NULL; 14 | } 15 | }; 16 | */ 17 | 18 | class Solution 19 | { 20 | private: 21 | void solve(Node *root , int &maxLen, int& maxSum, int len = 0, int sum = 0) { 22 | if(root == NULL){ 23 | if(len > maxLen){ 24 | maxLen = len; 25 | maxSum = sum; 26 | } 27 | else if(len == maxLen){ 28 | maxSum = max(sum,maxSum); 29 | } 30 | return; 31 | } 32 | sum += root->data; 33 | solve(root->left,maxLen,maxSum,len+1,sum); 34 | solve(root->right,maxLen,maxSum,len+1,sum); 35 | } 36 | public: 37 | 38 | int sumOfLongRootToLeafPath(Node *root) 39 | { 40 | int maxLen = 0; 41 | int maxSum = 0; 42 | 43 | //Recursive Function 44 | solve(root , maxLen , maxSum); 45 | 46 | return maxSum; 47 | } 48 | }; 49 | -------------------------------------------------------------------------------- /Tree/topView.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | struct Node{ 3 | int data; 4 | Node* left, right; 5 | }; 6 | */ 7 | class Solution 8 | { 9 | public: 10 | //Function to return a list of nodes visible from the top view 11 | //from left to right in Binary Tree. 12 | vector topView(Node *root) 13 | { 14 | vector ans; 15 | if(root == NULL){ 16 | return ans; 17 | } 18 | map mp; 19 | queue> q; 20 | q.push(make_pair(root,0)); 21 | while(!q.empty()){ 22 | pair temp = q.front(); 23 | q.pop(); 24 | 25 | Node* frontNode = temp.first; 26 | int horizontal_distance = temp.second; 27 | 28 | if(mp.find(horizontal_distance) == mp.end()){ 29 | mp[horizontal_distance] = frontNode->data; 30 | } 31 | if(frontNode -> left){ 32 | q.push(make_pair(frontNode -> left,horizontal_distance-1)); 33 | } 34 | if(frontNode -> right){ 35 | q.push(make_pair(frontNode -> right,horizontal_distance+1)); 36 | } 37 | } 38 | 39 | for(auto i : mp){ 40 | ans.push_back(i.second); 41 | } 42 | return ans; 43 | } 44 | }; 45 | -------------------------------------------------------------------------------- /Tree/verticalOrderTraversal.cpp: -------------------------------------------------------------------------------- 1 | class solution 2 | { 3 | public: 4 | // Function to find the vertical order traversal of Binary Tree. 5 | vector verticalOrder(Node *root) 6 | { 7 | vector ans; 8 | if (root == NULL) 9 | { 10 | return ans; 11 | } 12 | map>> mp; 13 | queue>> q; 14 | q.push(make_pair(root, make_pair(0, 0))); 15 | 16 | while (!q.empty()) 17 | { 18 | pair> temp = q.front(); 19 | q.pop(); 20 | Node *frontNode = temp.first; 21 | int no_line_dist = temp.second.first; 22 | int lvl = temp.second.second; 23 | 24 | mp[no_line_dist][lvl].push_back(frontNode->data); 25 | 26 | if (frontNode->left) 27 | { 28 | q.push(make_pair(frontNode->left, make_pair(no_line_dist - 1, lvl + 1))); 29 | } 30 | if (frontNode->right) 31 | { 32 | q.push(make_pair(frontNode->right, make_pair(no_line_dist + 1, lvl + 1))); 33 | } 34 | } 35 | for (auto i : mp) 36 | { 37 | for (auto j : i.second) 38 | { 39 | for (auto k : j.second) 40 | { 41 | ans.push_back(k); 42 | } 43 | } 44 | } 45 | return ans; 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /bit Manipulation/bitmask_flip_bit_index.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // Flip the bit at index i 5 | // Example: 6 | // x = 11 7 | // 0000 0000 0000 0000 0000 0000 0000 1011 8 | // flip the bit at index i = 1 9 | // 0000 0000 0000 0000 0000 0000 0000 1001 10 | // op = 9 11 | 12 | // Approach: 13 | // Now we have x = 11 14 | // 0000 0000 0000 0000 0000 0000 0000 1011 15 | // Lets create a mask of 1 16 | // 0000 0000 0000 0000 0000 0000 0000 0001 17 | // Now we must get set index of mask to ith index to get mast like this 18 | // 0000 0000 0000 0000 0000 0000 0000 0010 19 | // This we can get by left shifting 1 by i times 20 | 21 | // x = 0000 0000 0000 0000 0000 0000 0000 1011 22 | // mask = 0000 0000 0000 0000 0000 0000 0000 0010 23 | // Now we can do XOR operation to flip the bit at index i 24 | 25 | int flip_bit(int x, int i){ 26 | x = x ^ (1 << i); 27 | return x; 28 | } 29 | 30 | int main(){ 31 | int x = 11; 32 | int op = flip_bit(x, 1); 33 | cout << "x = " << x << endl; 34 | cout << "op = " << op << endl; 35 | return 0; 36 | } -------------------------------------------------------------------------------- /bit Manipulation/bitmask_remove_last_set_bit.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // Remove the last set bit 5 | // Logic1: x & (x - 1) 6 | // Logic2: x -= (x & -x) 7 | 8 | int remove_last_set_bit_1(int x){ 9 | x = x & (x - 1); 10 | return x; 11 | } 12 | int remove_last_set_bit_2(int x){ 13 | x -= (x & -1 * x); 14 | return x; 15 | } 16 | 17 | // Example: 18 | // x = 12 19 | // 0000 0000 0000 0000 0000 0000 0000 1100 20 | // remove the last set bit 21 | // 0000 0000 0000 0000 0000 0000 0000 1000 22 | // op = 8 23 | 24 | int main() 25 | { 26 | int x = 12; 27 | int op1 = remove_last_set_bit_1(x); 28 | int op2 = remove_last_set_bit_2(x); 29 | cout << "x = " << x << endl; 30 | cout << "op1 = " << op1 << endl; 31 | cout << "op2 = " << op2 << endl; 32 | return 0; 33 | } -------------------------------------------------------------------------------- /bit Manipulation/bitmask_set_index.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // Set the bit at index i 5 | // Example: 6 | // x = 11 7 | // 0000 0000 0000 0000 0000 0000 0000 1011 8 | // set the bit at index i = 2 9 | // 0000 0000 0000 0000 0000 0000 0000 1111 10 | // op x = 11 11 | 12 | // Approach: 13 | // Now we have x = 11 14 | // 0000 0000 0000 0000 0000 0000 0000 1011 15 | // Lets create a mask of 1 16 | // 0000 0000 0000 0000 0000 0000 0000 0001 17 | // Now we must get set index of mask to ith index to get mast like this 18 | // 0000 0000 0000 0000 0000 0000 0000 0100 19 | // This we can get by left shifting 1 by i times 20 | 21 | // x = 0000 0000 0000 0000 0000 0000 0000 1011 22 | // mask = 0000 0000 0000 0000 0000 0000 0000 0100 23 | 24 | // Now we can do OR operation to set the bit at index i 25 | 26 | int set_bit(int x, int i){ 27 | x = x | (1 << i); 28 | return x; 29 | } 30 | 31 | int main(){ 32 | int x = 11; 33 | int op = set_bit(x, 2); 34 | cout << "x = " << x << endl; 35 | cout << "op = " << op << endl; 36 | return 0; 37 | } -------------------------------------------------------------------------------- /bit Manipulation/bitmask_unset_index.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // Unset the bit at index i 5 | // Example: 6 | // x = 11 7 | // 0000 0000 0000 0000 0000 0000 0000 1011 8 | // unset the bit at index i = 1 9 | // 0000 0000 0000 0000 0000 0000 0000 1001 10 | // op = 9 11 | 12 | // Approach: 13 | // Now we have x = 11 14 | // 0000 0000 0000 0000 0000 0000 0000 1011 15 | // Lets create a mask of 1 16 | // 0000 0000 0000 0000 0000 0000 0000 0001 17 | // Now we must get set index of mask to ith index to get mast like this 18 | // 0000 0000 0000 0000 0000 0000 0000 0010 19 | // This we can get by left shifting 1 by i times 20 | 21 | // x = 0000 0000 0000 0000 0000 0000 0000 1011 22 | // mask = 0000 0000 0000 0000 0000 0000 0000 0010 23 | // ~mask = 1111 1111 1111 1111 1111 1111 1111 1101 24 | 25 | // Now we can do AND operation to unset the bit at index i 26 | 27 | int unset_bit(int x, int i){ 28 | x = x & ~(1 << i); 29 | return x; 30 | } 31 | 32 | int main(){ 33 | int x = 11; 34 | int op = unset_bit(x, 1); 35 | cout << "x = " << x << endl; 36 | cout << "op = " << op << endl; 37 | return 0; 38 | } -------------------------------------------------------------------------------- /lamda_function.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector sortStrBasedOnLen(vector& words) { 4 | int n = words.size(); 5 | // Define a lambda function as the comparison function 6 | auto compareByLength = [](string& s1, string& s2) { 7 | return s2.length() > s1.length(); 8 | }; 9 | sort(words.begin(), words.end(), compareByLength); 10 | 11 | return words; 12 | } 13 | }; 14 | --------------------------------------------------------------------------------