├── Arrays ├── All_distinct_subsequences.cpp ├── Binary-Search.cpp ├── Find_celebrity.cpp ├── Kadane's_Algorithm.cpp ├── Linear-Search.cpp ├── Moore's_Voting_Algorithm.cpp ├── Rotate_matrix_by_90_degrees.cpp └── Sieve_Aglo.cpp ├── Backtracking ├── Count_Number_of_Maximum_Bitwise-OR_Subsets.cpp ├── Knights_tour.cpp ├── Liars_puzzle.cpp ├── M_coloring_problem.cpp ├── Magic_square_problem.cpp ├── N_queens.cpp └── Restore_IP_Address.cpp ├── Dynamic Programming ├── 0_1Knapsack.cpp ├── Climbing_Stairs.cpp ├── Distinct_Subsequences.cpp ├── Egg_dropping_problem.cpp ├── Fibonacci_series.cpp ├── LIS_using_Binarysearch.cpp ├── Longest-Common-Subsequence.cpp ├── Longest-Increasing-Subsequence.cpp ├── Matrix-chain-multiplication.cpp ├── Palindrome-Partitioning.cpp ├── Regular_Expression_Matching.cpp ├── Rod_Cutting_Problem.cpp ├── Russian_doll_envelopes.cpp ├── Shortest_common_supersequence.cpp ├── Target_sum.cpp └── factorial_using_dp.cpp ├── Graphs ├── BFS.cpp ├── Bellman_Ford_Algorithm.cpp ├── DFS.cpp ├── Dijkstra’s_Algorithm.cpp ├── Floyd_Warshall_Algo.cpp ├── Graph_coloring_with_contraint.cpp ├── Kruskal's_Algorithm.cpp ├── Prim's_Algorithm.cpp ├── TopoSort.cpp ├── Travelling_Salesman.cpp ├── application-of-graphs │ └── flood_fill.cpp └── path_with_minimum_effort.cpp ├── Greedy Algorithms ├── Activity-selection-problem.cpp ├── Coin-Change.cpp ├── Huffman_coding.cpp └── Remove-K-Digits.cpp ├── Heaps ├── Heap_Implementation.cpp ├── Largest_triplet_product_in_stream.cpp ├── kth_smallest_element.cpp └── sort_k_sorted_array.cpp ├── Linked Lists ├── Detect_and_remove_loop.cpp ├── Flatten_Linked_List.cpp ├── Reverse-Linked-List.cpp └── find-cycle-in-linked-list.cpp ├── Queues ├── Circular_queue.cpp ├── Implementation.cpp ├── LRU_Cache.cpp ├── Reverse_first_k_elements.cpp └── Stack_using_queues.cpp ├── README.md ├── Recursion ├── Kth_symbol_in_grammar.cpp ├── N_Queens.cpp ├── Sudoku.cpp ├── Tower_of_hanoi.cpp ├── noOfSubseqwithSumk.cpp └── wildcard_matching.cpp ├── Sorting ├── 1_selection-sort.cpp ├── 2_bubble-sort.cpp ├── 3_insertion-sort.cpp ├── 4_merge-sort.cpp ├── 5_quick-sort.cpp ├── 6_heap-sort.cpp ├── 7_tim-sort.cpp ├── 8_shell-sort.cpp ├── 9_inplace-merge-sort.cpp ├── Dutch_national_flag.cpp └── Radix_Sort.cpp ├── Stacks ├── Asteroid_collision.cpp ├── Balanced-Parenthesis.cpp ├── Maximum_area_histogram.cpp ├── Stack-Implementation.cpp └── Trapping_rainwater.cpp └── Trees ├── AVL_Trees_Implementation.cpp ├── Inorder-Traversal.cpp ├── LCA_of_BST.cpp ├── Max_path_sum_in_BT.cpp ├── Morris_traversal.cpp ├── Postorder-Traversal.cpp ├── Preorder-Traversal.cpp ├── Red_Black_Trees_Implementation.cpp ├── Set-Using-Binary-Search-Tree.cpp ├── Zigzag_traversal.cpp ├── common_node_in_bst.cpp └── is_duplicate_subtree_in_tree.cpp /Arrays/All_distinct_subsequences.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int distinctSubsequences(string s) 4 | { 5 | int mod = 1e9 + 7; 6 | vectordp(s.length()+1); 7 | dp[0]=1; 8 | unordered_mapmp; 9 | for(int i=1;isecond; 15 | dp[i]=(dp[i]-dp[indx-1]+mod)%mod; 16 | } 17 | //dp[i] %= mod; 18 | mp[ch]=i; 19 | } 20 | return dp[s.size()]; 21 | } 22 | int main() 23 | { 24 | string s="abcbca"; 25 | cout << distinctSubsequences(s); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Arrays/Binary-Search.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int binarySearch(const vector& arr, int target) { 7 | int left = 0; 8 | int right = arr.size() - 1; 9 | 10 | while (left <= right) { 11 | int mid = left + (right - left) / 2; 12 | 13 | if (arr[mid] == target) { 14 | return mid; 15 | } else if (arr[mid] < target) { 16 | left = mid + 1; 17 | } else { 18 | right = mid - 1; 19 | } 20 | } 21 | 22 | return -1; 23 | } 24 | 25 | int main() { 26 | vector arr = {2, 4, 6, 8, 10, 12, 14, 16}; 27 | int target = 10; 28 | 29 | int result = binarySearch(arr, target); 30 | 31 | if (result != -1) { 32 | cout << "Element " << target << " found at index " << result << endl; 33 | } else { 34 | cout << "Element " << target << " not found in the array." << endl; 35 | } 36 | 37 | return 0; 38 | } 39 | -------------------------------------------------------------------------------- /Arrays/Find_celebrity.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | // Helper function to simulate whether person a knows person b 6 | bool knows(int a, int b, vector>& matrix) { 7 | return matrix[a][b] == 1; 8 | } 9 | 10 | // Function to find the celebrity 11 | int findCelebrity(int n, vector>& matrix) { 12 | // Step 1: Find the potential celebrity 13 | int celebrity = 0; 14 | for (int i = 1; i < n; i++) { 15 | // If celebrity knows i, then celebrity can't be the celebrity, update celebrity to i 16 | if (knows(celebrity, i, matrix)) { 17 | celebrity = i; 18 | } 19 | } 20 | 21 | // Step 2: Verify if the candidate is a real celebrity 22 | for (int i = 0; i < n; i++) { 23 | if (i != celebrity) { 24 | // Celebrity should not know anyone and everyone should know the celebrity 25 | if (knows(celebrity, i, matrix) || !knows(i, celebrity, matrix)) { 26 | return -1; // No celebrity found 27 | } 28 | } 29 | } 30 | 31 | return celebrity; 32 | } 33 | 34 | int main() { 35 | // Example: Matrix where person i knows person j 36 | vector> matrix = { 37 | {0, 1, 0}, 38 | {0, 0, 0}, 39 | {1, 1, 0} 40 | }; 41 | int n = matrix.size(); 42 | 43 | int celebrity = findCelebrity(n, matrix); 44 | 45 | if (celebrity == -1) { 46 | cout << "No celebrity found." << endl; 47 | } else { 48 | cout << "Celebrity is person " << celebrity << endl; 49 | } 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /Arrays/Kadane's_Algorithm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int main() 5 | { 6 | int n; 7 | cin>>n; 8 | 9 | int arr[n]; 10 | 11 | for(int i=0; i>arr[i]; 13 | 14 | int max_sum = INT_MIN, curr_sum =0; 15 | 16 | for(int i=0; i 2 | using namespace std; 3 | 4 | int Lsearch(int arr[], int size, int target) { 5 | for (int i = 0; i < size; ++i) { 6 | if (arr[i] == target) { 7 | return i; // Return the index where the target is found 8 | } 9 | } 10 | return -1; // Return -1 if the target is not found 11 | } 12 | 13 | int main() 14 | { 15 | int arr[] = {10, 25, 5, 15, 30}; 16 | int size = sizeof(arr) / sizeof(arr[0]); 17 | int target = 15; 18 | 19 | int result = Lsearch(arr, size, target); 20 | 21 | if (result != -1) { 22 | cout << "Target " << target << " found at index --> " << result << endl; 23 | } else { 24 | cout << "Target " << target << " not found in the array." << endl; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Arrays/Moore's_Voting_Algorithm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | // Function to find the majority element 7 | int findMajorityElement(vector& nums) { 8 | int candidate = 0, count = 0; 9 | 10 | // Step 1: Find the candidate for the majority element 11 | for (int num : nums) { 12 | if (count == 0) { 13 | candidate = num; 14 | } 15 | count += (num == candidate) ? 1 : -1; 16 | } 17 | 18 | // Step 2: Verify if the candidate is the majority element 19 | count = 0; 20 | for (int num : nums) { 21 | if (num == candidate) { 22 | count++; 23 | } 24 | } 25 | 26 | if (count > nums.size() / 2) { 27 | return candidate; 28 | } else { 29 | return -1; // No majority element found 30 | } 31 | } 32 | 33 | int main() { 34 | vector nums = {2, 2, 1, 1, 2, 2, 2}; // Example array 35 | int result = findMajorityElement(nums); 36 | 37 | if (result != -1) { 38 | cout << "The majority element is: " << result << endl; 39 | } else { 40 | cout << "There is no majority element." << endl; 41 | } 42 | 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /Arrays/Rotate_matrix_by_90_degrees.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | // Function to rotate the matrix by 90 degrees clockwise 6 | void rotateMatrix(vector>& matrix) { 7 | int n = matrix.size(); 8 | 9 | // Step 1: Transpose the matrix (swap matrix[i][j] with matrix[j][i]) 10 | for (int i = 0; i < n; i++) { 11 | for (int j = i; j < n; j++) { 12 | swap(matrix[i][j], matrix[j][i]); 13 | } 14 | } 15 | 16 | // Step 2: Reverse each row 17 | for (int i = 0; i < n; i++) { 18 | reverse(matrix[i].begin(), matrix[i].end()); 19 | } 20 | } 21 | 22 | // Function to print the matrix 23 | void printMatrix(const vector>& matrix) { 24 | for (const auto& row : matrix) { 25 | for (int val : row) { 26 | cout << val << " "; 27 | } 28 | cout << endl; 29 | } 30 | } 31 | 32 | int main() { 33 | vector> matrix = { 34 | {1, 2, 3}, 35 | {4, 5, 6}, 36 | {7, 8, 9} 37 | }; 38 | 39 | cout << "Original Matrix:" << endl; 40 | printMatrix(matrix); 41 | 42 | rotateMatrix(matrix); 43 | 44 | cout << "Matrix after 90-degree rotation:" << endl; 45 | printMatrix(matrix); 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /Arrays/Sieve_Aglo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | vector sieve_prime(int n) 7 | { 8 | vector sieve(n + 1 ,false) ; 9 | 10 | sieve[0] = sieve[1] = true ; 11 | 12 | for(int i=2; i * i <= n ; i++) 13 | { 14 | if(!sieve[i]) 15 | { 16 | for(long long j = (long long)i*i ; j <= n ; j += i) 17 | sieve[j] = true ; 18 | } 19 | } 20 | 21 | vector primes ; 22 | 23 | for(int i = 2 ; i <= n ; i++) 24 | { 25 | if(!sieve[i] ) primes.push_back(i) ; 26 | } 27 | 28 | return primes ; 29 | } 30 | 31 | int main() 32 | { 33 | vector A = sieve_prime(10) ; // They are 4 primes till 10: {2, 3, 5, 7} 34 | vector B = sieve_prime(20) ; // There are 8 primes till 20: {2, 3, 5, 7, 11, 13, 17, 19} 35 | 36 | for(auto it : A) cout << it << " " ; 37 | cout << endl ; 38 | 39 | for(auto it : B) cout << it << " " ; 40 | cout << endl ; 41 | 42 | return 0; 43 | } -------------------------------------------------------------------------------- /Backtracking/Count_Number_of_Maximum_Bitwise-OR_Subsets.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | class Solution { 6 | public: 7 | int solve(int i, int ors, int maxi, vector& nums) { 8 | if(i >= nums.size()) { 9 | return (ors == maxi) ? 1 : 0; 10 | } 11 | 12 | int cnt = 0; 13 | cnt += solve(i + 1, ors | nums[i], maxi, nums); 14 | cnt += solve(i + 1, ors, maxi, nums); 15 | 16 | return cnt; 17 | } 18 | 19 | int countMaxOrSubsets(vector& nums) { 20 | int maxi = 0; 21 | 22 | for(auto it: nums) { 23 | maxi |= it; 24 | } 25 | 26 | return solve(0, 0, maxi, nums); 27 | } 28 | }; 29 | 30 | int main() { 31 | Solution solution; 32 | int n; 33 | 34 | cout << "Enter the number of elements in the array: "; 35 | cin >> n; 36 | 37 | vector nums(n); 38 | cout << "Enter the elements: "; 39 | for (int i = 0; i < n; ++i) { 40 | cin >> nums[i]; 41 | } 42 | 43 | int result = solution.countMaxOrSubsets(nums); 44 | cout << "The number of subsets with the maximum OR value is: " << result << endl; 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /Backtracking/Knights_tour.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | #define N 8 6 | 7 | bool isSafe(int x, int y, vector> &board) { 8 | return (x >= 0 && x < N && y >= 0 && y < N && board[x][y] == -1); 9 | } 10 | 11 | void printSolution(vector> &board) { 12 | for (int x = 0; x < N; x++) { 13 | for (int y = 0; y < N; y++) { 14 | cout << board[x][y] << " "; 15 | } 16 | cout << endl; 17 | } 18 | } 19 | 20 | bool solveKTUtil(int x, int y, int movei, vector> &board, int xMove[], int yMove[]) { 21 | int k, next_x, next_y; 22 | if (movei == N * N) return true; 23 | for (k = 0; k < 8; k++) { 24 | next_x = x + xMove[k]; 25 | next_y = y + yMove[k]; 26 | if (isSafe(next_x, next_y, board)) { 27 | board[next_x][next_y] = movei; 28 | if (solveKTUtil(next_x, next_y, movei + 1, board, xMove, yMove)) return true; 29 | else board[next_x][next_y] = -1; 30 | } 31 | } 32 | return false; 33 | } 34 | 35 | bool solveKT() { 36 | vector> board(N, vector(N, -1)); 37 | int xMove[8] = {2, 1, -1, -2, -2, -1, 1, 2}; 38 | int yMove[8] = {1, 2, 2, 1, -1, -2, -2, -1}; 39 | board[0][0] = 0; 40 | if (!solveKTUtil(0, 0, 1, board, xMove, yMove)) { 41 | cout << "Solution does not exist"; 42 | return false; 43 | } else { 44 | printSolution(board); 45 | } 46 | return true; 47 | } 48 | 49 | int main() { 50 | solveKT(); 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /Backtracking/Liars_puzzle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | // Global variables 6 | int N; // Number of people 7 | vector> statements; // statements[i][j] = 1 if i says j is truthful, -1 if i says j is a liar 8 | vector truth; // truth[i] = 1 if i is truthful, 0 if i is a liar 9 | 10 | // Check if the current configuration of truthfulness is valid 11 | bool isValidConfiguration() { 12 | for (int i = 0; i < N; i++) { 13 | for (int j = 0; j < N; j++) { 14 | if (statements[i][j] != 0) { 15 | // If person i is truthful 16 | if (truth[i] == 1) { 17 | if (statements[i][j] == 1 && truth[j] == 0) return false; // i says j is truthful but j is a liar 18 | if (statements[i][j] == -1 && truth[j] == 1) return false; // i says j is a liar but j is truthful 19 | } 20 | // If person i is a liar 21 | else { 22 | if (statements[i][j] == 1 && truth[j] == 1) return false; // i lies, says j is truthful, but j is truthful 23 | if (statements[i][j] == -1 && truth[j] == 0) return false; // i lies, says j is a liar, but j is a liar 24 | } 25 | } 26 | } 27 | } 28 | return true; 29 | } 30 | 31 | // Backtracking to find a valid truth/lie assignment 32 | bool solve(int person) { 33 | if (person == N) { 34 | return isValidConfiguration(); 35 | } 36 | 37 | // Try assuming person is truthful 38 | truth[person] = 1; 39 | if (solve(person + 1)) return true; 40 | 41 | // Try assuming person is a liar 42 | truth[person] = 0; 43 | if (solve(person + 1)) return true; 44 | 45 | return false; 46 | } 47 | 48 | int main() { 49 | cout << "Enter the number of people: "; 50 | cin >> N; 51 | 52 | statements.resize(N, vector(N)); 53 | truth.resize(N); 54 | 55 | cout << "Enter the statements matrix (1: truthful, -1: liar, 0: no statement):\n"; 56 | for (int i = 0; i < N; i++) { 57 | for (int j = 0; j < N; j++) { 58 | cin >> statements[i][j]; 59 | } 60 | } 61 | 62 | if (solve(0)) { 63 | cout << "A valid solution was found:\n"; 64 | for (int i = 0; i < N; i++) { 65 | cout << "Person " << i + 1 << " is " << (truth[i] ? "Truthful" : "Liar") << endl; 66 | } 67 | } else { 68 | cout << "No valid solution exists.\n"; 69 | } 70 | 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /Backtracking/M_coloring_problem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | // Function to check if the current color assignment is safe for vertex v 6 | bool isSafe(int v, vector> &graph, vector &color, int c, int V) { 7 | for (int i = 0; i < V; i++) { 8 | if (graph[v][i] == 1 && color[i] == c) { 9 | return false; // Adjacent vertex has the same color 10 | } 11 | } 12 | return true; 13 | } 14 | 15 | // A recursive utility function to solve the M-Coloring problem 16 | bool solveMColoring(int v, vector> &graph, vector &color, int m, int V) { 17 | // Base case: All vertices have been assigned a color 18 | if (v == V) { 19 | return true; 20 | } 21 | 22 | // Try assigning each color (from 1 to m) to vertex v 23 | for (int c = 1; c <= m; c++) { 24 | // Check if assigning color c to vertex v is valid 25 | if (isSafe(v, graph, color, c, V)) { 26 | color[v] = c; // Assign color c to vertex v 27 | 28 | // Recur to assign colors to the remaining vertices 29 | if (solveMColoring(v + 1, graph, color, m, V)) { 30 | return true; 31 | } 32 | 33 | // If assigning color c doesn't lead to a solution, backtrack 34 | color[v] = 0; 35 | } 36 | } 37 | 38 | // If no color can be assigned to this vertex, return false 39 | return false; 40 | } 41 | 42 | // Function to solve the M-Coloring problem using backtracking 43 | bool graphColoring(vector> &graph, int m, int V) { 44 | // Initialize all vertices as unassigned (color 0) 45 | vector color(V, 0); 46 | 47 | // Call the utility function to solve the problem 48 | if (solveMColoring(0, graph, color, m, V)) { 49 | // If a solution is found, print the color assignment 50 | cout << "Solution Exists: Following are the assigned colors\n"; 51 | for (int i = 0; i < V; i++) { 52 | cout << "Vertex " << i + 1 << " ---> Color " << color[i] << "\n"; 53 | } 54 | return true; 55 | } else { 56 | // If no solution is found 57 | cout << "No solution exists\n"; 58 | return false; 59 | } 60 | } 61 | 62 | int main() { 63 | int V = 4; // Number of vertices 64 | vector> graph = { 65 | {0, 1, 1, 1}, 66 | {1, 0, 1, 0}, 67 | {1, 1, 0, 1}, 68 | {1, 0, 1, 0} 69 | }; 70 | int m = 3; // Number of colors 71 | 72 | // Solve the M-Coloring problem 73 | graphColoring(graph, m, V); 74 | 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /Backtracking/Magic_square_problem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | const int N = 3; // Change N for different grid sizes 6 | int magicConstant = N * (N * N + 1) / 2; 7 | 8 | bool isSafe(vector>& magicSquare, int row, int col, int num) { 9 | // Check if the number is already used 10 | for (int i = 0; i < N; i++) { 11 | for (int j = 0; j < N; j++) { 12 | if (magicSquare[i][j] == num) return false; 13 | } 14 | } 15 | return true; 16 | } 17 | 18 | // Function to check if current grid is a valid magic square 19 | bool isMagicSquare(vector>& magicSquare) { 20 | // Check row sums 21 | for (int i = 0; i < N; i++) { 22 | int rowSum = 0; 23 | for (int j = 0; j < N; j++) { 24 | rowSum += magicSquare[i][j]; 25 | } 26 | if (rowSum != magicConstant) return false; 27 | } 28 | 29 | // Check column sums 30 | for (int j = 0; j < N; j++) { 31 | int colSum = 0; 32 | for (int i = 0; i < N; i++) { 33 | colSum += magicSquare[i][j]; 34 | } 35 | if (colSum != magicConstant) return false; 36 | } 37 | 38 | // Check diagonal sums 39 | int diagSum1 = 0, diagSum2 = 0; 40 | for (int i = 0; i < N; i++) { 41 | diagSum1 += magicSquare[i][i]; 42 | diagSum2 += magicSquare[i][N - i - 1]; 43 | } 44 | 45 | return diagSum1 == magicConstant && diagSum2 == magicConstant; 46 | } 47 | 48 | bool solveMagicSquare(vector>& magicSquare, int row, int col) { 49 | // If we are at the end of the square and it's valid, return true 50 | if (row == N && isMagicSquare(magicSquare)) return true; 51 | 52 | // If we are at the end of a row, move to the next row 53 | if (col == N) return solveMagicSquare(magicSquare, row + 1, 0); 54 | 55 | // Try placing numbers from 1 to N*N in the current cell 56 | for (int num = 1; num <= N * N; num++) { 57 | if (isSafe(magicSquare, row, col, num)) { 58 | magicSquare[row][col] = num; 59 | 60 | // Recur to place the next number 61 | if (solveMagicSquare(magicSquare, row, col + 1)) { 62 | return true; 63 | } 64 | 65 | // If placing num doesn't lead to a solution, backtrack 66 | magicSquare[row][col] = 0; 67 | } 68 | } 69 | 70 | return false; // Trigger backtracking 71 | } 72 | 73 | void printMagicSquare(const vector>& magicSquare) { 74 | for (int i = 0; i < N; i++) { 75 | for (int j = 0; j < N; j++) { 76 | cout << magicSquare[i][j] << "\t"; 77 | } 78 | cout << endl; 79 | } 80 | } 81 | 82 | int main() { 83 | vector> magicSquare(N, vector(N, 0)); 84 | 85 | if (solveMagicSquare(magicSquare, 0, 0)) { 86 | cout << "Magic Square:" << endl; 87 | printMagicSquare(magicSquare); 88 | } else { 89 | cout << "No solution exists!" << endl; 90 | } 91 | 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /Backtracking/N_queens.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | class NQueens { 7 | private: 8 | int N; 9 | int solutionsCount = 0; 10 | vector queens; // queens[i] represents the column of the queen in row i 11 | vector columns; // Track columns where queens are placed 12 | vector diag1; // Track \ diagonals (row - col) 13 | vector diag2; // Track / diagonals (row + col) 14 | vector> allSolutions; 15 | 16 | // Helper function to add the current solution to allSolutions 17 | void addSolution() { 18 | vector solution(N, string(N, '.')); 19 | for (int i = 0; i < N; ++i) { 20 | solution[i][queens[i]] = 'Q'; 21 | } 22 | allSolutions.push_back(solution); 23 | } 24 | 25 | // Backtracking function 26 | void solve(int row) { 27 | if (row == N) { // All queens are placed 28 | solutionsCount++; 29 | addSolution(); 30 | return; 31 | } 32 | 33 | for (int col = 0; col < N; ++col) { 34 | if (columns[col] || diag1[row - col + N - 1] || diag2[row + col]) 35 | continue; // Skip if there's a conflict 36 | 37 | queens[row] = col; 38 | columns[col] = diag1[row - col + N - 1] = diag2[row + col] = true; 39 | 40 | solve(row + 1); // Move to the next row 41 | 42 | // Backtrack 43 | columns[col] = diag1[row - col + N - 1] = diag2[row + col] = false; 44 | } 45 | } 46 | 47 | public: 48 | NQueens(int n) : N(n), queens(n), columns(n, false), diag1(2 * n - 1, false), diag2(2 * n - 1, false) {} 49 | 50 | void findSolutions() { 51 | solve(0); 52 | cout << "Total Solutions: " << solutionsCount << "\n\n"; 53 | printAllSolutions(); 54 | } 55 | 56 | // Function to print all solutions 57 | void printAllSolutions() { 58 | for (const auto& solution : allSolutions) { 59 | for (const auto& row : solution) { 60 | cout << row << "\n"; 61 | } 62 | cout << "\n"; 63 | } 64 | } 65 | }; 66 | 67 | int main() { 68 | int n; 69 | cout << "Enter the value of N: "; 70 | cin >> n; 71 | 72 | NQueens solver(n); 73 | solver.findSolutions(); 74 | 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /Backtracking/Restore_IP_Address.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | bool isValid(const string &s) { 7 | if (s.size() > 3 || s.empty() || (s[0] == '0' && s.size() > 1) || stoi(s) > 255) { 8 | return false; 9 | } 10 | return true; 11 | } 12 | 13 | void backtrack(const string &s, int start, int part, string current, vector &result) { 14 | if (part == 4 && start == s.size()) { 15 | result.push_back(current); 16 | return; 17 | } 18 | if (part == 4 || start == s.size()) { 19 | return; 20 | } 21 | 22 | for (int len = 1; len <= 3 && start + len <= s.size(); ++len) { 23 | string segment = s.substr(start, len); 24 | if (isValid(segment)) { 25 | string newCurrent = current + segment + (part == 3 ? "" : "."); 26 | backtrack(s, start + len, part + 1, newCurrent, result); 27 | } 28 | } 29 | } 30 | 31 | vector restoreIpAddresses(const string &s) { 32 | vector result; 33 | if (s.size() > 12) { 34 | return result; 35 | } 36 | backtrack(s, 0, 0, "", result); 37 | return result; 38 | } 39 | 40 | int main() { 41 | string s; 42 | cout << "Enter the string: "; 43 | cin >> s; 44 | vector ips = restoreIpAddresses(s); 45 | cout << "Valid IP addresses are:" << endl; 46 | for (const string &ip : ips) { 47 | cout << ip << endl; 48 | } 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /Dynamic Programming/0_1Knapsack.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Time Complexity: O(N*W) 3 | 4 | Reason: There are N*W states therefore at max ‘N*W’ new problems will be solved. 5 | 6 | Space Complexity: O(N*W) + O(N) 7 | 8 | Reason: We are using a recursion stack space(O(N)) and a 2D array ( O(N*W)). 9 | */ 10 | #include 11 | using namespace std; 12 | 13 | // Function to solve the 0/1 Knapsack problem using memoization 14 | int knapsackUtil(vector& wt, vector& val, int ind, int W, vector>& dp) { 15 | // Base case: If there are no items left or the knapsack has no capacity, return 0 16 | if (ind == 0 || W == 0) { 17 | return 0; 18 | } 19 | 20 | // If the result for this state is already calculated, return it 21 | if (dp[ind][W] != -1) { 22 | return dp[ind][W]; 23 | } 24 | 25 | // Calculate the maximum value by either excluding the current item or including it 26 | int notTaken = knapsackUtil(wt, val, ind - 1, W, dp); 27 | int taken = 0; 28 | 29 | // Check if the current item can be included without exceeding the knapsack's capacity 30 | if (wt[ind] <= W) { 31 | taken = val[ind] + knapsackUtil(wt, val, ind - 1, W - wt[ind], dp); 32 | } 33 | 34 | // Store the result in the DP table and return 35 | return dp[ind][W] = max(notTaken, taken); 36 | } 37 | 38 | // Function to solve the 0/1 Knapsack problem 39 | int knapsack(vector& wt, vector& val, int n, int W) { 40 | vector> dp(n, vector(W + 1, -1)); 41 | return knapsackUtil(wt, val, n - 1, W, dp); 42 | } 43 | 44 | int main() { 45 | vector wt = {1, 2, 4, 5}; 46 | vector val = {5, 4, 8, 6}; 47 | int W = 5; 48 | int n = wt.size(); 49 | 50 | cout << "The Maximum value of items the thief can steal is " << knapsack(wt, val, n, W); 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /Dynamic Programming/Climbing_Stairs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int climbStairs(int n) { 5 | if (n <= 1) { 6 | return 1; 7 | } 8 | 9 | std::vector dp(n + 1, 0); 10 | dp[0] = 1; 11 | dp[1] = 1; 12 | 13 | for (int i = 2; i <= n; ++i) { 14 | dp[i] = dp[i - 1] + dp[i - 2]; 15 | } 16 | 17 | return dp[n]; 18 | } 19 | 20 | int main() { 21 | int n; 22 | cout << "Enter the number of stairs: "; 23 | cin >> n; 24 | 25 | int ways = climbStairs(n); 26 | cout << "Number of distinct ways to climb " << n << " stairs: " << ways << std::endl; 27 | 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /Dynamic Programming/Distinct_Subsequences.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // Function to count distinct subsequences 5 | int countDistinctSubsequences(const std::string& str) { 6 | const int MOD = 1e9 + 7; 7 | int n = str.length(); 8 | 9 | // dp array to store the count of distinct subsequences 10 | std::vector dp(n + 1, 0); 11 | 12 | // Initialize the array for an empty string 13 | dp[0] = 1; 14 | 15 | // Map to store the last index of each character 16 | std::unordered_map lastOccurrence; 17 | 18 | for (int i = 1; i <= n; ++i) { 19 | dp[i] = (2 * dp[i - 1]) % MOD; 20 | 21 | // If the current character has occurred before 22 | if (lastOccurrence.find(str[i - 1]) != lastOccurrence.end()) { 23 | // Subtract the count of subsequences ending with the previous occurrence 24 | dp[i] = (dp[i] - dp[lastOccurrence[str[i - 1]] - 1] + MOD) % MOD; 25 | } 26 | 27 | // Update the last occurrence index of the current character 28 | lastOccurrence[str[i - 1]] = i; 29 | } 30 | 31 | return dp[n]; 32 | } 33 | 34 | int main() { 35 | std::string str = "abcabc"; 36 | std::cout << "Number of distinct subsequences: " << countDistinctSubsequences(str) << std::endl; 37 | 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /Dynamic Programming/Egg_dropping_problem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int dp[201][201]; 8 | 9 | int solve(int e, int f) { 10 | if (f == 0 || f == 1) { 11 | return f; 12 | } 13 | 14 | if (e == 1) { 15 | return f; 16 | } 17 | 18 | if (dp[e][f] != -1) { 19 | return dp[e][f]; 20 | } 21 | 22 | int mini = INT_MAX; 23 | for (int k = 1; k <= f; k++) { 24 | int first = (dp[e - 1][k - 1] != -1) ? dp[e - 1][k - 1] : solve(e - 1, k - 1); 25 | 26 | int second = (dp[e][f - k] != -1) ? dp[e][f - k] : solve(e, f - k); 27 | 28 | int ans = 1 + max(first, second); 29 | 30 | mini = min(mini, ans); 31 | } 32 | 33 | return dp[e][f] = mini; 34 | } 35 | 36 | int eggDrop(int e, int f) { 37 | memset(dp, -1, sizeof(dp)); 38 | return solve(e, f); 39 | } 40 | 41 | int main() { 42 | int eggs = 2; 43 | int floors = 10; 44 | 45 | int minAttempts = eggDrop(eggs, floors); 46 | 47 | cout << "Minimum attempts needed: " << minAttempts << endl; 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /Dynamic Programming/Fibonacci_series.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | std::vector memo; 5 | 6 | long long fibonacci(int n) { 7 | if (n <= 1) { 8 | return n; 9 | } 10 | 11 | if (memo[n] != -1) { 12 | return memo[n]; 13 | } 14 | 15 | memo[n] = fibonacci(n - 1) + fibonacci(n - 2); 16 | return memo[n]; 17 | } 18 | 19 | int main() { 20 | int n; 21 | std::cout << "Enter the value of n: "; 22 | std::cin >> n; 23 | 24 | memo.resize(n + 1, -1); 25 | 26 | std::cout << "Fibonacci series up to " << n << " terms:\n"; 27 | for (int i = 0; i <= n; ++i) { 28 | std::cout << fibonacci(i) << " "; 29 | } 30 | std::cout << std::endl; 31 | 32 | return 0; 33 | } 34 | Enter 35 | -------------------------------------------------------------------------------- /Dynamic Programming/LIS_using_Binarysearch.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int lis(int a[], int n) { 5 | vector t; 6 | t.push_back(a[0]); 7 | 8 | int length = 1; 9 | 10 | for (int i = 1; i < n; i++) { 11 | if (a[i] > t.back()) { 12 | t.push_back(a[i]); 13 | length++; 14 | } else { 15 | int index = lower_bound(t.begin(), t.end(), a[i]) - t.begin(); 16 | t[index] = a[i]; 17 | } 18 | } 19 | 20 | return length; 21 | } 22 | 23 | int main() { 24 | int arr[] = {10, 0, 1, 5, 2, 7, 221, 118}; 25 | int n = sizeof(arr) / sizeof(arr[0]); 26 | 27 | cout << "The length of the longest increasing subsequence is " << lis(arr, n); 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Dynamic Programming/Longest-Common-Subsequence.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | string longestCommonSubsequence(string text1, string text2) { 8 | int m = text1.length(); 9 | int n = text2.length(); 10 | 11 | vector> dp(m + 1, vector(n + 1, 0)); 12 | 13 | for (int i = 1; i <= m; i++) { 14 | for (int j = 1; j <= n; j++) { 15 | if (text1[i - 1] == text2[j - 1]) { 16 | dp[i][j] = dp[i - 1][j - 1] + 1; 17 | } else { 18 | dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); 19 | } 20 | } 21 | } 22 | 23 | int i = m, j = n; 24 | string lcs; 25 | while (i > 0 && j > 0) { 26 | if (text1[i - 1] == text2[j - 1]) { 27 | lcs = text1[i - 1] + lcs; 28 | i--; 29 | j--; 30 | } else if (dp[i - 1][j] > dp[i][j - 1]) { 31 | i--; 32 | } else { 33 | j--; 34 | } 35 | } 36 | 37 | return lcs; 38 | } 39 | 40 | int main() { 41 | string text1 = "ABCBDAB"; 42 | string text2 = "BDCAB"; 43 | 44 | string lcs = longestCommonSubsequence(text1, text2); 45 | 46 | cout << "Longest Common Subsequence: " << lcs << endl; 47 | 48 | return 0; 49 | } 50 | Enter 51 | -------------------------------------------------------------------------------- /Dynamic Programming/Longest-Increasing-Subsequence.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | The longest increasing subsequence is described as a subsequence of an array where: 3 | 4 | All elements of the subsequence are in increasing order. 5 | This subsequence itself is of the longest length possible. 6 | */ 7 | 8 | #include 9 | using namespace std; 10 | 11 | // Function to find the length of the longest increasing subsequence 12 | int getAns(int arr[], int n, int ind, int prev_index, vector>& dp) { 13 | // Base condition 14 | if (ind == n) 15 | return 0; 16 | 17 | if (dp[ind][prev_index + 1] != -1) 18 | return dp[ind][prev_index + 1]; 19 | 20 | int notTake = 0 + getAns(arr, n, ind + 1, prev_index, dp); 21 | 22 | int take = 0; 23 | 24 | if (prev_index == -1 || arr[ind] > arr[prev_index]) { 25 | take = 1 + getAns(arr, n, ind + 1, ind, dp); 26 | } 27 | 28 | return dp[ind][prev_index + 1] = max(notTake, take); 29 | } 30 | 31 | int longestIncreasingSubsequence(int arr[], int n) { 32 | // Create a 2D DP array initialized to -1 33 | vector> dp(n, vector(n + 1, -1)); 34 | 35 | return getAns(arr, n, 0, -1, dp); 36 | } 37 | 38 | int main() { 39 | int arr[] = {10, 9, 2, 5, 3, 7, 101, 18}; 40 | int n = sizeof(arr) / sizeof(arr[0]); 41 | 42 | cout << "The length of the longest increasing subsequence is " << longestIncreasingSubsequence(arr, n); 43 | 44 | return 0; 45 | } 46 | 47 | /* 48 | Time Complexity: O(N*N) 49 | 50 | Reason: There are N*N states therefore at max ‘N*N’ new problems will be solved. 51 | 52 | Space Complexity: O(N*N) + O(N) 53 | 54 | Reason: We are using an auxiliary recursion stack space(O(N)) (see the recursive tree, in the worst case we will go till N calls at a time) and a 2D array ( O(N*N+1)). 55 | */ 56 | -------------------------------------------------------------------------------- /Dynamic Programming/Matrix-chain-multiplication.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | int matrixChainMultiplication(vector& dimensions) { 7 | int n = dimensions.size() - 1; 8 | vector> dp(n, vector(n, 0)); 9 | 10 | for (int chainLength = 2; chainLength <= n; chainLength++) { 11 | for (int i = 0; i < n - chainLength + 1; i++) { 12 | int j = i + chainLength - 1; 13 | dp[i][j] = INT_MAX; 14 | 15 | for (int k = i; k < j; k++) { 16 | dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j] + dimensions[i] * dimensions[k + 1] * dimensions[j + 1]); 17 | } 18 | } 19 | } 20 | return dp[0][n - 1]; 21 | } 22 | 23 | int main() { 24 | vector dimensions = {10, 30, 5, 60}; 25 | int minMultiplications = matrixChainMultiplication(dimensions); 26 | 27 | cout << "Minimum number of scalar multiplications: " << minMultiplications << endl; 28 | 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /Dynamic Programming/Palindrome-Partitioning.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // Function to check if a substring is a palindrome. 5 | bool isPalindrome(int i, int j, string &s) { 6 | while (i < j) { 7 | if (s[i] != s[j]) return false; 8 | i++; 9 | j--; 10 | } 11 | return true; 12 | } 13 | 14 | // Recursive function to find the minimum number of partitions to make palindromes. 15 | int minPartitions(int i, int n, string &str, vector &dp) { 16 | // Base case: If we've reached the end of the string. 17 | if (i == n) return 0; 18 | 19 | if (dp[i] != -1) return dp[i]; 20 | int minCost = INT_MAX; 21 | // Consider all possible substrings starting from the current index. 22 | for (int j = i; j < n; j++) { 23 | if (isPalindrome(i, j, str)) { 24 | // If the substring is a palindrome, calculate the cost and minimize it. 25 | int cost = 1 + minPartitions(j + 1, n, str, dp); 26 | minCost = min(minCost, cost); 27 | } 28 | } 29 | return dp[i] = minCost; 30 | } 31 | 32 | // Main function to find the minimum number of partitions for palindrome partitioning. 33 | int palindromePartitioning(string str) { 34 | int n = str.size(); 35 | vector dp(n, -1); 36 | // Calling the recursive function and subtracting 1 as it counts partitions, not cuts. 37 | return minPartitions(0, n, str, dp) - 1; 38 | } 39 | 40 | int main() { 41 | string str = "BABABCBADCEDE"; 42 | int partitions = palindromePartitioning(str); 43 | cout << "The minimum number of partitions: " << partitions << "\n"; 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /Dynamic Programming/Regular_Expression_Matching.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | bool isMatch(const string &s, const string &p) { 6 | int m = s.size(), n = p.size(); 7 | vector> dp(m + 1, vector(n + 1, false)); 8 | dp[0][0] = true; 9 | 10 | for (int j = 1; j <= n; ++j) { 11 | if (p[j - 1] == '*') { 12 | dp[0][j] = dp[0][j - 2]; 13 | } 14 | } 15 | 16 | for (int i = 1; i <= m; ++i) { 17 | for (int j = 1; j <= n; ++j) { 18 | if (p[j - 1] == s[i - 1] || p[j - 1] == '.') { 19 | dp[i][j] = dp[i - 1][j - 1]; 20 | } else if (p[j - 1] == '*') { 21 | dp[i][j] = dp[i][j - 2] || (dp[i - 1][j] && (s[i - 1] == p[j - 2] || p[j - 2] == '.')); 22 | } 23 | } 24 | } 25 | 26 | return dp[m][n]; 27 | } 28 | 29 | int main() { 30 | string s, p; 31 | cout << "Enter the string: "; 32 | cin >> s; 33 | cout << "Enter the pattern: "; 34 | cin >> p; 35 | if (isMatch(s, p)) { 36 | cout << "The pattern matches the string." << endl; 37 | } else { 38 | cout << "The pattern does not match the string." << endl; 39 | } 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /Dynamic Programming/Rod_Cutting_Problem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int rodCutting(vector& price, int n) { 8 | vector dp(n + 1, 0); 9 | 10 | for (int i = 1; i <= n; ++i) { 11 | int max_val = INT_MIN; 12 | for (int j = 1; j <= i; ++j) { 13 | max_val = max(max_val, price[j - 1] + dp[i - j]); 14 | } 15 | dp[i] = max_val; 16 | } 17 | 18 | return dp[n]; 19 | } 20 | 21 | int main() { 22 | vector price = {1, 5, 8, 9, 10, 17, 17, 20}; 23 | int n = price.size(); 24 | 25 | cout << "Maximum obtainable value is " << rodCutting(price, n) << endl; 26 | 27 | return 0; 28 | } 29 | Enter 30 | -------------------------------------------------------------------------------- /Dynamic Programming/Russian_doll_envelopes.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int maxEnvelopes(vector>& envelopes) { 8 | if (envelopes.empty()) return 0; 9 | 10 | sort(envelopes.begin(), envelopes.end(), [](const auto& a, const auto& b) { 11 | return a.first == b.first ? b.second < a.second : a.first < b.first; 12 | }); 13 | 14 | int n = envelopes.size(); 15 | vector dp(n, 1); 16 | 17 | for (int i = 1; i < n; ++i) { 18 | for (int j = 0; j < i; ++j) { 19 | if (envelopes[i].second > envelopes[j].second) { 20 | dp[i] = max(dp[i], dp[j] + 1); 21 | } 22 | } 23 | } 24 | 25 | return *max_element(dp.begin(), dp.end()); 26 | } 27 | 28 | int main() { 29 | vector> envelopes = {{5,4}, {6,4}, {6,7}, {2,3}}; 30 | cout << "Maximum number of envelopes that can be nested: " << maxEnvelopes(envelopes) << endl; 31 | 32 | return 0; 33 | } 34 | Enter 35 | -------------------------------------------------------------------------------- /Dynamic Programming/Shortest_common_supersequence.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int shortestCommonSupersequence(const string& str1, const string& str2) { 8 | int m = str1.length(); 9 | int n = str2.length(); 10 | vector> dp(m + 1, vector(n + 1, 0)); 11 | for (int i = 0; i <= m; ++i) { 12 | for (int j = 0; j <= n; ++j) { 13 | if (i == 0 || j == 0) 14 | dp[i][j] = i + j; 15 | else if (str1[i - 1] == str2[j - 1]) 16 | dp[i][j] = 1 + dp[i - 1][j - 1]; 17 | else 18 | dp[i][j] = 1 + min(dp[i - 1][j], dp[i][j - 1]); 19 | } 20 | } 21 | return dp[m][n]; 22 | } 23 | 24 | string constructSCS(const string& str1, const string& str2) { 25 | int m = str1.length(); 26 | int n = str2.length(); 27 | vector> dp(m + 1, vector(n + 1, 0)); 28 | 29 | for (int i = 0; i <= m; ++i) { 30 | for (int j = 0; j <= n; ++j) { 31 | if (i == 0 || j == 0) 32 | dp[i][j] = i + j; 33 | else if (str1[i - 1] == str2[j - 1]) 34 | dp[i][j] = 1 + dp[i - 1][j - 1]; 35 | else 36 | dp[i][j] = 1 + min(dp[i - 1][j], dp[i][j - 1]); 37 | } 38 | } 39 | int i = m, j = n; 40 | string result; 41 | while (i > 0 && j > 0) { 42 | if (str1[i - 1] == str2[j - 1]) { 43 | result = str1[i - 1] + result; 44 | i--; 45 | j--; 46 | } else { 47 | if (dp[i - 1][j] < dp[i][j - 1]) { 48 | result = str1[i - 1] + result; 49 | i--; 50 | } else { 51 | result = str2[j - 1] + result; 52 | j--; 53 | } 54 | } 55 | } 56 | 57 | while (i > 0) { 58 | result = str1[i - 1] + result; 59 | i--; 60 | } 61 | while (j > 0) { 62 | result = str2[j - 1] + result; 63 | j--; 64 | } 65 | return result; 66 | } 67 | 68 | int main() { 69 | string str1, str2; 70 | cout << "Enter the first string: "; 71 | cin >> str1; 72 | cout << "Enter the second string: "; 73 | cin >> str2; 74 | int scsLength = shortestCommonSupersequence(str1, str2); 75 | string scs = constructSCS(str1, str2); 76 | cout << "Shortest Common Supersequence Length: " << scsLength << endl; 77 | cout << "Shortest Common Supersequence: " << scs << endl; 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /Dynamic Programming/Target_sum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | int subsetSum(vector& arr, int n, int sum) { 6 | vector> dp(n + 1, vector(sum + 1, 0)); 7 | dp[0][0] = 1; 8 | for (int i = 1; i < n + 1; i++) { 9 | for (int j = 0; j < sum + 1; j++) { 10 | if (arr[i - 1] <= j) { 11 | dp[i][j] = dp[i - 1][j - arr[i - 1]] + dp[i - 1][j]; 12 | } else { 13 | dp[i][j] = dp[i - 1][j]; 14 | } 15 | } 16 | } 17 | return dp[n][sum]; 18 | } 19 | 20 | int findTargetSumWays(vector& arr, int target) { 21 | int n = arr.size(); 22 | int sum = 0; 23 | for (int i = 0; i < n; i++) { 24 | sum += arr[i]; 25 | } 26 | 27 | if ((sum + target) % 2 != 0) { 28 | return 0; 29 | } 30 | int targetSum = (sum + target) / 2; 31 | return subsetSum(arr, n, targetSum); 32 | } 33 | 34 | int main() { 35 | vector arr = {1, 1, 1, 1, 1}; 36 | int target = 3; 37 | 38 | int ways = findTargetSumWays(arr, target); 39 | 40 | cout << "Number of ways to achieve the target sum: " << ways << endl; 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /Dynamic Programming/factorial_using_dp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int dp[1000] = {0}; 5 | 6 | int fact(int n) { 7 | if (n >= 0) { 8 | dp[0] = 1; 9 | for (int i = 1; i <= n; ++i) { 10 | dp[i] = i * dp[i - 1]; 11 | } 12 | return dp[n]; 13 | } 14 | return 0; 15 | } 16 | 17 | int main() { 18 | int n; 19 | cin>>n; 20 | if(n==0) cout<<"0"< 2 | using namespace std; 3 | 4 | class Graph { 5 | public: 6 | int V; 7 | vector> adj; 8 | 9 | Graph(int V); 10 | void addEdge(int u, int v); 11 | void BFS(int v, vector& visited); 12 | }; 13 | 14 | Graph::Graph(int V) : V(V) { 15 | adj.resize(V); 16 | } 17 | 18 | void Graph::addEdge(int u, int v) { 19 | adj[u].push_back(v); 20 | adj[v].push_back(u); // For undirected graph 21 | } 22 | 23 | void Graph::BFS(int v, vector& visited) { 24 | queue q; 25 | visited[v] = true; 26 | q.push(v); 27 | 28 | while (!q.empty()) { 29 | v = q.front(); 30 | cout << v << " "; 31 | q.pop(); 32 | 33 | for (int u : adj[v]) { 34 | if (!visited[u]) { 35 | visited[u] = true; 36 | q.push(u); 37 | } 38 | } 39 | } 40 | } 41 | 42 | int main() { 43 | int V = 7; 44 | Graph g(V); 45 | 46 | g.addEdge(0, 1); 47 | g.addEdge(0, 2); 48 | g.addEdge(1, 2); 49 | g.addEdge(1, 3); 50 | g.addEdge(2, 4); 51 | g.addEdge(3, 5); 52 | g.addEdge(4, 5); 53 | g.addEdge(4, 6); 54 | 55 | vector visited(V, false); 56 | 57 | cout << "BFS starting from vertex 0:\n"; 58 | g.BFS(0, visited); 59 | 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /Graphs/Bellman_Ford_Algorithm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | struct Edge { 8 | int source, destination, weight; 9 | }; 10 | 11 | void bellmanFord(vector& edges, int vertices, int source) { 12 | vector distance(vertices, numeric_limits::max()); 13 | distance[source] = 0; 14 | 15 | for (int i = 0; i < vertices - 1; ++i) { 16 | for (const auto& edge : edges) { 17 | if (distance[edge.source] != numeric_limits::max() && 18 | distance[edge.source] + edge.weight < distance[edge.destination]) { 19 | distance[edge.destination] = distance[edge.source] + edge.weight; 20 | } 21 | } 22 | } 23 | 24 | for (const auto& edge : edges) { 25 | if (distance[edge.source] != numeric_limits::max() && 26 | distance[edge.source] + edge.weight < distance[edge.destination]) { 27 | cout << "Graph contains negative cycle!" << endl; 28 | return; 29 | } 30 | } 31 | 32 | cout << "Vertex Distance from source" << endl; 33 | for (int i = 0; i < vertices; ++i) { 34 | cout << i << "\t\t" << distance[i] << endl; 35 | } 36 | } 37 | 38 | int main() { 39 | vector edges = { 40 | {0, 1, -1}, 41 | {0, 2, 4}, 42 | {1, 2, 3}, 43 | {1, 3, 2}, 44 | {1, 4, 2}, 45 | {3, 2, 5}, 46 | {3, 1, 1}, 47 | {4, 3, -3} 48 | }; 49 | 50 | int vertices = 5; 51 | int source = 0; 52 | 53 | bellmanFord(edges, vertices, source); 54 | 55 | return 0; 56 | } 57 | Enter 58 | -------------------------------------------------------------------------------- /Graphs/DFS.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Graph { 5 | public: 6 | int V; 7 | vector> adj; 8 | 9 | Graph(int V); 10 | void addEdge(int u, int v); 11 | void DFS(int v, vector& visited); 12 | }; 13 | 14 | Graph::Graph(int V) : V(V) { 15 | adj.resize(V); 16 | } 17 | 18 | void Graph::addEdge(int u, int v) { 19 | adj[u].push_back(v); 20 | adj[v].push_back(u); // For undirected graph 21 | } 22 | 23 | void Graph::DFS(int v, vector& visited) { 24 | visited[v] = true; 25 | cout << v << " "; 26 | 27 | for (int u : adj[v]) { 28 | if (!visited[u]) { 29 | DFS(u, visited); 30 | } 31 | } 32 | } 33 | 34 | int main() { 35 | int V = 7; 36 | Graph g(V); 37 | 38 | g.addEdge(0, 1); 39 | g.addEdge(0, 2); 40 | g.addEdge(1, 2); 41 | g.addEdge(1, 3); 42 | g.addEdge(2, 4); 43 | g.addEdge(3, 5); 44 | g.addEdge(4, 5); 45 | g.addEdge(4, 6); 46 | 47 | vector visited(V, false); 48 | 49 | cout << "DFS starting from vertex 0:\n"; 50 | g.DFS(0, visited); 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /Graphs/Dijkstra’s_Algorithm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Dijkstra 5 | { 6 | public: 7 | vector shortestDistance(int V, vector>>& adj, int S) 8 | { 9 | priority_queue, vector>, greater>> pq; 10 | vector distTo(V, INT_MAX); 11 | distTo[S] = 0; 12 | pq.push({0, S}); 13 | 14 | while (!pq.empty()) 15 | { 16 | int node = pq.top().second; 17 | int dis = pq.top().first; 18 | pq.pop(); 19 | 20 | for (auto it : adj[node]) 21 | { 22 | int v = it.first; 23 | int w = it.second; 24 | if (dis + w < distTo[v]) 25 | { 26 | distTo[v] = dis + w; 27 | pq.push({distTo[v], v}); 28 | } 29 | } 30 | } 31 | 32 | return distTo; 33 | } 34 | }; 35 | 36 | int main() 37 | { 38 | int V = 3, E = 6, S = 2; 39 | vector>> adj(V); 40 | 41 | vector> v1 = {{1, 1}, {2, 6}}; 42 | vector> v2 = {{2, 3}, {0, 1}}; 43 | vector> v3 = {{1, 3}, {0, 6}}; 44 | 45 | adj[0] = v1; 46 | adj[1] = v2; 47 | adj[2] = v3; 48 | 49 | Dijkstra obj; 50 | vector res = obj.shortestDistance(V, adj, S); 51 | 52 | for (int i = 0; i < V; i++) 53 | { 54 | cout << res[i] << " "; 55 | } 56 | cout << endl; 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /Graphs/Floyd_Warshall_Algo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | const int INF = 1e9; 7 | 8 | void floydWarshall(vector>& graph, int V) { 9 | vector> dist(V, vector(V, INF)); 10 | 11 | for (int i = 0; i < V; ++i) 12 | dist[i][i] = 0; 13 | 14 | for (int i = 0; i < V; ++i) 15 | for (int j = 0; j < V; ++j) 16 | if (graph[i][j] != INF) 17 | dist[i][j] = graph[i][j]; 18 | 19 | for (int k = 0; k < V; ++k) 20 | for (int i = 0; i < V; ++i) 21 | for (int j = 0; j < V; ++j) 22 | if (dist[i][k] != INF && dist[k][j] != INF && dist[i][k] + dist[k][j] < dist[i][j]) 23 | dist[i][j] = dist[i][k] + dist[k][j]; 24 | 25 | cout << "Shortest distances between all pairs of vertices:\n"; 26 | for (int i = 0; i < V; ++i) { 27 | for (int j = 0; j < V; ++j) { 28 | if (dist[i][j] == INF) 29 | cout << "INF\t"; 30 | else 31 | cout << dist[i][j] << "\t"; 32 | } 33 | cout << "\n"; 34 | } 35 | } 36 | 37 | int main() { 38 | vector> graph = { 39 | {0, INF, -2, INF}, 40 | {4, 0, 3, INF}, 41 | {INF, INF, 0, 2}, 42 | {INF, -1, INF, 0} 43 | }; 44 | 45 | int V = graph.size(); 46 | 47 | floydWarshall(graph, V); 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /Graphs/Graph_coloring_with_contraint.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | // Define a graph structure 9 | class Graph { 10 | public: 11 | int V; // Number of vertices 12 | vector> adj; // Adjacency list 13 | 14 | Graph(int V) : V(V), adj(V) {} 15 | 16 | void addEdge(int u, int v) { 17 | adj[u].push_back(v); 18 | adj[v].push_back(u); 19 | } 20 | }; 21 | 22 | // Function to check if the color assignment is safe for the vertex v 23 | bool isSafe(int v, int color, vector& colors, const Graph& graph, 24 | const unordered_map>& constraints) { 25 | // Check adjacency constraints 26 | for (int neighbor : graph.adj[v]) { 27 | if (colors[neighbor] == color) return false; 28 | } 29 | // Check additional constraints if any 30 | if (constraints.find(v) != constraints.end() && 31 | constraints.at(v).find(color) == constraints.at(v).end()) { 32 | return false; 33 | } 34 | return true; 35 | } 36 | 37 | // Function for backtracking with MRV (minimum remaining values) heuristic 38 | bool graphColoringUtil(Graph& graph, int m, vector& colors, 39 | const unordered_map>& constraints, 40 | int coloredCount = 0) { 41 | if (coloredCount == graph.V) return true; // All vertices are colored 42 | 43 | // Minimum remaining values (MRV): find vertex with least available colors 44 | int vertex = -1, minOptions = m + 1; 45 | for (int v = 0; v < graph.V; ++v) { 46 | if (colors[v] == -1) { 47 | int available = 0; 48 | for (int c = 1; c <= m; ++c) { 49 | if (isSafe(v, c, colors, graph, constraints)) ++available; 50 | } 51 | if (available < minOptions) { 52 | minOptions = available; 53 | vertex = v; 54 | } 55 | } 56 | } 57 | 58 | if (vertex == -1) return false; // No valid vertex found 59 | 60 | // Try assigning colors to vertex with MRV 61 | for (int c = 1; c <= m; ++c) { 62 | if (isSafe(vertex, c, colors, graph, constraints)) { 63 | colors[vertex] = c; 64 | if (graphColoringUtil(graph, m, colors, constraints, coloredCount + 1)) { 65 | return true; 66 | } 67 | colors[vertex] = -1; // Backtrack 68 | } 69 | } 70 | 71 | return false; 72 | } 73 | 74 | // Function to solve the graph coloring problem 75 | bool graphColoring(Graph& graph, int m, unordered_map>& constraints) { 76 | vector colors(graph.V, -1); // -1 indicates no color assigned 77 | return graphColoringUtil(graph, m, colors, constraints); 78 | } 79 | 80 | int main() { 81 | int V = 5; // Number of vertices 82 | int m = 3; // Number of colors 83 | 84 | Graph graph(V); 85 | graph.addEdge(0, 1); 86 | graph.addEdge(0, 2); 87 | graph.addEdge(1, 3); 88 | graph.addEdge(1, 4); 89 | graph.addEdge(2, 3); 90 | graph.addEdge(3, 4); 91 | 92 | // Define constraints on colors 93 | unordered_map> constraints; 94 | constraints[0] = {1}; // Vertex 0 must be color 1 95 | constraints[3] = {2, 3}; // Vertex 3 can only be color 2 or 3 96 | 97 | // Solve the coloring problem 98 | if (graphColoring(graph, m, constraints)) { 99 | cout << "Solution exists\n"; 100 | } else { 101 | cout << "No solution exists\n"; 102 | } 103 | 104 | return 0; 105 | } 106 | -------------------------------------------------------------------------------- /Graphs/Kruskal's_Algorithm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Kruskal { 5 | int* parent; 6 | int* rank; 7 | 8 | public: 9 | Kruskal(int n) 10 | { 11 | parent = new int[n]; 12 | rank = new int[n]; 13 | 14 | for (int i = 0; i < n; i++) { 15 | parent[i] = -1; 16 | rank[i] = 1; 17 | } 18 | } 19 | int find(int i) 20 | { 21 | if (parent[i] == -1) 22 | return i; 23 | 24 | return parent[i] = find(parent[i]); 25 | } 26 | void unite(int x, int y) 27 | { 28 | int s1 = find(x); 29 | int s2 = find(y); 30 | 31 | if (s1 != s2) { 32 | if (rank[s1] < rank[s2]) { 33 | parent[s1] = s2; 34 | } 35 | else if (rank[s1] > rank[s2]) { 36 | parent[s2] = s1; 37 | } 38 | else { 39 | parent[s2] = s1; 40 | rank[s1] += 1; 41 | } 42 | } 43 | } 44 | }; 45 | 46 | class Graph { 47 | vector > edgelist; 48 | int V; 49 | 50 | public: 51 | Graph(int V) { this->V = V; } 52 | 53 | void addEdge(int x, int y, int w) 54 | { 55 | edgelist.push_back({ w, x, y }); 56 | } 57 | 58 | void kruskals_mst() 59 | { 60 | sort(edgelist.begin(), edgelist.end()); 61 | 62 | Kruskal s(V); 63 | int ans = 0; 64 | cout << "Following are the edges in the " 65 | "constructed MST" 66 | << endl; 67 | for (auto edge : edgelist) { 68 | int w = edge[0]; 69 | int x = edge[1]; 70 | int y = edge[2]; 71 | 72 | 73 | if (s.find(x) != s.find(y)) { 74 | s.unite(x, y); 75 | ans += w; 76 | cout << x << " -- " << y << " == " << w 77 | << endl; 78 | } 79 | } 80 | cout << "Minimum Cost Spanning Tree: " << ans; 81 | } 82 | }; 83 | 84 | int main() 85 | { 86 | Graph g(4); 87 | g.addEdge(0, 1, 10); 88 | g.addEdge(1, 3, 15); 89 | g.addEdge(2, 3, 4); 90 | g.addEdge(2, 0, 6); 91 | g.addEdge(0, 3, 5); 92 | 93 | g.kruskals_mst(); 94 | 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /Graphs/Prim's_Algorithm.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Solution 5 | { 6 | public: 7 | // Function to find sum of weights of edges of the Minimum Spanning Tree. 8 | int spanningTree(int V, vector> adj[]) 9 | { 10 | priority_queue, 11 | vector>, greater>> pq; 12 | 13 | vector visited(V, 0); 14 | // {weight, node} 15 | pq.push({0, 0}); 16 | int totalWeight = 0; 17 | while (!pq.empty()) 18 | { 19 | auto curr = pq.top(); 20 | pq.pop(); 21 | int node = curr.second; 22 | int weight = curr.first; 23 | 24 | if (visited[node] == 1) 25 | continue; 26 | // Add the node to the MST 27 | visited[node] = 1; 28 | totalWeight += weight; 29 | for (auto neighbor : adj[node]) 30 | { 31 | int adjNode = neighbor[0]; 32 | int edgeWeight = neighbor[1]; 33 | if (!visited[adjNode]) 34 | { 35 | pq.push({edgeWeight, adjNode}); 36 | } 37 | } 38 | } 39 | return totalWeight; 40 | } 41 | }; 42 | 43 | int main() 44 | { 45 | int V = 6; 46 | vector> edges = {{0, 1, 2}, {0, 2, 4}, {1, 2, 1}, {1, 3, 3}, {2, 3, 2}, {3, 4, 5}, {3, 5, 6}, {4, 5, 1}}; 47 | vector> adj[V]; 48 | for (auto edge : edges) 49 | { 50 | vector temp(2); 51 | temp[0] = edge[1]; 52 | temp[1] = edge[2]; 53 | adj[edge[0]].push_back(temp); 54 | 55 | temp[0] = edge[0]; 56 | temp[1] = edge[2]; 57 | adj[edge[1]].push_back(temp); 58 | } 59 | 60 | Solution obj; 61 | int sum = obj.spanningTree(V, adj); 62 | cout << "The sum of all the edge weights in the Minimum Spanning Tree: " << sum << endl; 63 | 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /Graphs/TopoSort.cpp: -------------------------------------------------------------------------------- 1 | // Question)Given a graph, find the topological order for the given graph. 2 | 3 | // Topological sort: The linear ordering of nodes/vertices such that if there 4 | // exists an edge between 2 nodes u,v then ‘u’ appears before ‘v’. 5 | // Example: 6 | // Example: 7 | // 6 5 8 | // 1 2 9 | // 2 5 10 | // 3 6 11 | // 5 3 12 | // 2 4 13 | 14 | // Output- 15 | // 1 2 5 4 3 6 16 | 17 | #include 18 | using namespace std; 19 | #define ll long long 20 | #define vll vector 21 | 22 | class Solution 23 | { 24 | public: 25 | // Function to perform Topological Sorting 26 | vll topo(ll N, vll adj[]) 27 | { 28 | // Create a queue to perform BFS 29 | queue q; 30 | 31 | // Create an array to store the in-degrees of all nodes 32 | vll indegree(N + 1, 0); 33 | 34 | // Calculate in-degrees for all nodes 35 | for (ll i = 1; i <= N; i++) 36 | { 37 | for (auto it : adj[i]) 38 | { 39 | indegree[it]++; 40 | } 41 | } 42 | 43 | // Initialize the queue with nodes having in-degree 0 44 | for (ll i = 1; i <= N; i++) 45 | { 46 | if (indegree[i] == 0) 47 | { 48 | q.push(i); 49 | } 50 | } 51 | 52 | // Initialize the result vector to store the topological order 53 | vll topo; 54 | 55 | // Perform BFS to find the topological order 56 | while (!q.empty()) 57 | { 58 | ll node = q.front(); 59 | q.pop(); 60 | topo.push_back(node); 61 | 62 | // Update in-degrees of adjacent nodes and push to queue if in-degree becomes 0 63 | for (auto it : adj[node]) 64 | { 65 | indegree[it]--; 66 | if (indegree[it] == 0) 67 | { 68 | q.push(it); 69 | } 70 | } 71 | } 72 | 73 | return topo; // Return the topological order 74 | } 75 | }; 76 | 77 | int main() 78 | { 79 | ll n, edges; 80 | cin >> n >> edges; 81 | 82 | // Create an adjacency list to represent the directed graph 83 | vll adj[n + 1]; 84 | for (ll i = 0; i < edges; i++) 85 | { 86 | ll x, y; 87 | cin >> x >> y; 88 | adj[x].push_back(y); // Adding directed edge from x to y 89 | } 90 | 91 | Solution obj; 92 | vll v = obj.topo(n, adj); // Perform Topological Sorting 93 | for (auto it : v) 94 | cout << it << " "; // Print the topological order 95 | 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /Graphs/Travelling_Salesman.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | #define V 4 // Number of vertices in the graph (cities) 7 | 8 | // Function to calculate the total cost of visiting a path (tour) 9 | int calculateCost(vector>& graph, vector& path) { 10 | int cost = 0; 11 | for (int i = 0; i < path.size() - 1; i++) { 12 | cost += graph[path[i]][path[i+1]]; // Cost from current city to next city 13 | } 14 | cost += graph[path.back()][path[0]]; // Returning to the start city 15 | return cost; 16 | } 17 | 18 | // Function to find the minimum cost tour using backtracking 19 | void tspBacktrack(vector>& graph, vector& path, vector& visited, int currentCity, int count, int currentCost, int& minCost) { 20 | if (count == V && graph[currentCity][0] != 0) { 21 | // We've visited all cities and can return to the starting city 22 | int totalCost = currentCost + graph[currentCity][0]; 23 | minCost = min(minCost, totalCost); 24 | return; 25 | } 26 | 27 | // Explore all unvisited cities 28 | for (int i = 0; i < V; i++) { 29 | if (!visited[i] && graph[currentCity][i] != 0) { 30 | visited[i] = true; 31 | path.push_back(i); 32 | tspBacktrack(graph, path, visited, i, count + 1, currentCost + graph[currentCity][i], minCost); 33 | // Backtrack 34 | path.pop_back(); 35 | visited[i] = false; 36 | } 37 | } 38 | } 39 | 40 | int tsp(vector>& graph) { 41 | vector path; // To store the current tour 42 | vector visited(V, false); // To track visited cities 43 | int minCost = INT_MAX; // Store the minimum tour cost 44 | path.push_back(0); // Start the tour from city 0 45 | visited[0] = true; 46 | 47 | // Start the backtracking from the first city 48 | tspBacktrack(graph, path, visited, 0, 1, 0, minCost); 49 | 50 | return minCost; 51 | } 52 | 53 | int main() { 54 | // Distance matrix (adjacency matrix of the graph) 55 | vector> graph = { 56 | {0, 10, 15, 20}, 57 | {10, 0, 35, 25}, 58 | {15, 35, 0, 30}, 59 | {20, 25, 30, 0} 60 | }; 61 | 62 | int minCost = tsp(graph); 63 | cout << "The minimum cost of the TSP tour is: " << minCost << endl; 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /Graphs/application-of-graphs/flood_fill.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | class bucket { 4 | public: 5 | void dfs(int i, int j,vector>&image,int newColor,int*ti,int*tj){ 6 | int oldclr=image[i][j]; 7 | image[i][j]=newColor; 8 | for(int k=0;k<4;k++){ 9 | int x=i+ti[k]; 10 | int y=j+tj[k]; 11 | if(x>=0&&y>=0&&x> floodFill(vector>& image, int sr, int sc, int newColor) { 16 | if(image[sr][sc]==newColor)return image; 17 | int ti[4]={-1,0,1,0}; 18 | int tj[4]={0,1,0,-1}; 19 | dfs(sr,sc,image,newColor,ti,tj); 20 | return image; 21 | } 22 | }; 23 | int main(){ 24 | vector>image={{1,1,1},{1,1,0},{1,0,1}}; 25 | int new_clr=2,x=1,y=1; // (x,y) are coordinates. 26 | bucket b1; 27 | b1.floodFill(image,x,y,new_clr); 28 | //after flood-fill 29 | for(int i=0;i<3;i++){ 30 | for(int j=0;j<3;j++) 31 | cout< 2 | using namespace std; 3 | class Solution { 4 | public: 5 | int minimumEffortPath(vector>& heights) { 6 | int n=heights.size(); 7 | int m=heights[0].size(); 8 | if(n==1&&m==1)return 0; 9 | int min_ef=0; 10 | int ti[]={-1,0,1,0}; 11 | int tj[]={0,1,0,-1}; 12 | int px=-1,py=-1; 13 | priority_queue> , vector>>, greater>> > pq; 14 | pq.push({0,{0,0}}); 15 | vector>dist(n,vector(m,INT_MAX)); 16 | dist[0][0]=0; 17 | while(!pq.empty()){ 18 | auto it=pq.top();pq.pop(); 19 | int diff=it.first; 20 | int x=it.second.first; 21 | int y=it.second.second; 22 | if(x==n-1&&y==m-1)return diff; 23 | for(int i=0;i<4;i++){ 24 | int tx=x+ti[i]; 25 | int ty=y+tj[i]; 26 | if(tx>=0&&ty>=0&&tx> heights = {{1, 2, 2}, {3, 8, 2}, {5, 3, 5}}; 41 | Solution obj; 42 | int ans = obj.MinimumEffort(heights); 43 | cout << ans; 44 | cout << endl; 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /Greedy Algorithms/Activity-selection-problem.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct Activity { 6 | int start; 7 | int end; 8 | }; 9 | 10 | bool sortByEndTime(const Activity &a, const Activity &b) { 11 | return a.end < b.end; 12 | } 13 | 14 | void activitySelection(std::vector &activities) { 15 | int n = activities.size(); 16 | 17 | // Sort activities by end time 18 | std::sort(activities.begin(), activities.end(), sortByEndTime); 19 | 20 | std::vector selectedActivities; 21 | selectedActivities.push_back(activities[0]); 22 | 23 | int prevEnd = activities[0].end; 24 | 25 | for (int i = 1; i < n; ++i) { 26 | if (activities[i].start >= prevEnd) { 27 | selectedActivities.push_back(activities[i]); 28 | prevEnd = activities[i].end; 29 | } 30 | } 31 | 32 | std::cout << "Selected activities:" << std::endl; 33 | for (const Activity &activity : selectedActivities) { 34 | std::cout << "Start: " << activity.start << " End: " << activity.end << std::endl; 35 | } 36 | } 37 | 38 | int main() { 39 | // Example activities data 40 | std::vector activities = { 41 | {1, 3}, 42 | {2, 4}, 43 | {3, 5}, 44 | {5, 7}, 45 | {6, 8}, 46 | {8, 10} 47 | }; 48 | 49 | activitySelection(activities); 50 | 51 | return 0; 52 | } 53 | Enter 54 | -------------------------------------------------------------------------------- /Greedy Algorithms/Coin-Change.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int denomination[] = {1, 2, 5, 10, 20, 50, 100, 500, 1000}; 5 | int n = sizeof(denomination) / sizeof(denomination[0]); 6 | 7 | void findMin(int V) { 8 | sort(denomination, denomination + n); 9 | vector ans; 10 | 11 | for (int i = n - 1; i >= 0; i--) { 12 | while (V >= denomination[i]) { 13 | V -= denomination[i]; 14 | ans.push_back(denomination[i]); 15 | } 16 | } 17 | 18 | for (int i = 0; i < ans.size(); i++) 19 | cout << ans[i] << " "; 20 | } 21 | 22 | int main() { 23 | int n = 93; 24 | cout << "Following is minimal number of change for " << n << ": "; 25 | findMin(n); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /Greedy Algorithms/Huffman_coding.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | struct MinHeapNode { 5 | char data; 6 | unsigned freq; 7 | MinHeapNode *left, *right; 8 | MinHeapNode(char data, unsigned freq) { 9 | left = right = nullptr; 10 | this->data = data; 11 | this->freq = freq; 12 | } 13 | }; 14 | 15 | struct compare { 16 | bool operator()(MinHeapNode* l, MinHeapNode* r) { 17 | return (l->freq > r->freq); 18 | } 19 | }; 20 | 21 | void printCodes(struct MinHeapNode* root, string str) { 22 | if (!root) 23 | return; 24 | if (root->data != '$') 25 | cout << root->data << ": " << str << "\n"; 26 | printCodes(root->left, str + "0"); 27 | printCodes(root->right, str + "1"); 28 | } 29 | 30 | void HuffmanCodes(char data[], int freq[], int size) { 31 | struct MinHeapNode *left, *right, *top; 32 | priority_queue, compare> minHeap; 33 | for (int i = 0; i < size; ++i) 34 | minHeap.push(new MinHeapNode(data[i], freq[i])); 35 | while (minHeap.size() != 1) { 36 | left = minHeap.top(); 37 | minHeap.pop(); 38 | right = minHeap.top(); 39 | minHeap.pop(); 40 | top = new MinHeapNode('$', left->freq + right->freq); 41 | top->left = left; 42 | top->right = right; 43 | minHeap.push(top); 44 | } 45 | printCodes(minHeap.top(), ""); 46 | } 47 | 48 | int main() { 49 | char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' }; 50 | int freq[] = { 5, 9, 12, 13, 16, 45 }; 51 | int size = sizeof(arr) / sizeof(arr[0]); 52 | HuffmanCodes(arr, freq, size); 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /Greedy Algorithms/Remove-K-Digits.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 402. Remove K Digits 3 | Difficulty: Medium 4 | Link: https://leetcode.com/problems/remove-k-digits/description/ 5 | 6 | Given string num representing a non-negative integer num, and an integer k, 7 | return the smallest possible integer after removing k digits from num. 8 | 9 | Example 1: 10 | 11 | Input: num = "1432219", k = 3 12 | Output: "1219" 13 | Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest. 14 | 15 | Example 2: 16 | 17 | Input: num = "10200", k = 1 18 | Output: "200" 19 | Explanation: Remove the leading 1 and the number is 200. Note that the output must not contain 20 | leading zeroes. 21 | 22 | Example 3: 23 | 24 | Input: num = "10", k = 2 25 | Output: "0" 26 | Explanation: Remove all the digits from the number and it is left with nothing which is 0. 27 | 28 | */ 29 | 30 | #include 31 | using namespace std; 32 | 33 | string removeKdigits(string num, int k) { 34 | // Remove first k characters which start decreasing order 35 | deque q; 36 | int rem = k; 37 | for(auto c: num) { 38 | while(q.size() and rem and q.back() > c) q.pop_back(), rem--; 39 | q.push_back(c); 40 | } 41 | // If k characters not removed and double ended queue still contain digits 42 | while(rem and q.size()) { 43 | q.pop_back(); 44 | rem--; 45 | } 46 | // Store final number 47 | string final; 48 | while(q.size()) { 49 | if(!(final.empty() and q.front() == '0')) final.push_back(q.front()); 50 | q.pop_front(); 51 | } 52 | // If final empty, put final as 0 53 | if(final == "") final = "0"; 54 | return final; 55 | } 56 | 57 | int main() { 58 | string s; 59 | cout<<"Enter Number: "; 60 | cin>>s; 61 | int k; 62 | cout<<"Enter K: "; 63 | cin>>k; 64 | 65 | cout<<"Smallest Number after removing K Digits: "< 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int main() { 8 | // Creating a min-heap 9 | priority_queue, greater> minHeap; 10 | 11 | // Inserting elements into the heap 12 | minHeap.push(3); 13 | minHeap.push(1); 14 | minHeap.push(4); 15 | minHeap.push(1); 16 | minHeap.push(5); 17 | 18 | // Accessing the top element (minimum in this case) 19 | cout << "Top element: " << minHeap.top() << endl; 20 | 21 | // Removing the top element 22 | minHeap.pop(); 23 | 24 | // Accessing the new top element 25 | cout << "Top element after pop: " << minHeap.top() << endl; 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /Heaps/Largest_triplet_product_in_stream.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int largestTripletProduct(vector& nums) { 8 | int n = nums.size(); 9 | if (n < 3) { 10 | cout << "Not enough elements in the stream." << endl; 11 | return -1; 12 | } 13 | 14 | priority_queue, greater> minHeap; 15 | priority_queue, less> maxHeap; 16 | 17 | int tripletProduct = -1; 18 | 19 | for (int i = 0; i < n; ++i) { 20 | int currentNum = nums[i]; 21 | 22 | maxHeap.push(currentNum); 23 | if (maxHeap.size() > 3) { 24 | maxHeap.pop(); 25 | } 26 | 27 | minHeap.push(currentNum); 28 | if (minHeap.size() > 2) { 29 | minHeap.pop(); 30 | } 31 | 32 | if (maxHeap.size() == 3) { 33 | int maxProduct = maxHeap.top() * maxHeap.top(); 34 | maxHeap.pop(); 35 | maxProduct *= maxHeap.top(); 36 | tripletProduct = max(tripletProduct, maxProduct); 37 | } 38 | } 39 | 40 | return tripletProduct; 41 | } 42 | 43 | int main() { 44 | vector nums = {1, 10, 2, 6, 5, 3}; 45 | int result = largestTripletProduct(nums); 46 | cout << "Largest Triplet Product: " << result << endl; 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /Heaps/kth_smallest_element.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int kthSmallest(vector& nums, int k) { 7 | priority_queue maxHeap; 8 | for (int num : nums) { 9 | maxHeap.push(num); 10 | 11 | if (maxHeap.size() > k) { 12 | maxHeap.pop(); 13 | } 14 | } 15 | return maxHeap.top(); 16 | } 17 | 18 | int main() { 19 | vector nums = {3, 1, 4, 2, 7, 5, 6}; 20 | int k = 3; 21 | int result = kthSmallest(nums, k); 22 | cout << result << endl; 23 | return 0; 24 | } -------------------------------------------------------------------------------- /Heaps/sort_k_sorted_array.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | void kSortedArraySort(vector& arr, int k) { 8 | priority_queue, greater> minHeap; 9 | for (int i = 0; i <= k; ++i) { 10 | minHeap.push(arr[i]); 11 | } 12 | 13 | int index = 0; 14 | 15 | for (int i = k + 1; i < arr.size(); ++i) { 16 | arr[index++] = minHeap.top(); 17 | minHeap.pop(); 18 | minHeap.push(arr[i]); 19 | } 20 | 21 | while (!minHeap.empty()) { 22 | arr[index++] = minHeap.top(); 23 | minHeap.pop(); 24 | } 25 | } 26 | 27 | void printArray(const vector& arr) { 28 | for (int num : arr) { 29 | cout << num << " "; 30 | } 31 | cout << endl; 32 | } 33 | 34 | int main() { 35 | vector arr = {6, 5, 3, 2, 8, 10, 9}; 36 | int k = 3; 37 | 38 | printArray(arr); 39 | kSortedArraySort(arr, k); 40 | printArray(arr); 41 | 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /Linked Lists/Detect_and_remove_loop.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | // Node structure for the linked list 5 | struct Node { 6 | int data; 7 | Node* next; 8 | Node(int val) { 9 | data = val; 10 | next = nullptr; 11 | } 12 | }; 13 | 14 | // Function to detect and remove loop in a linked list 15 | void detectAndRemoveLoop(Node* head) { 16 | if (!head || !head->next) { 17 | return; // No loop if the list is empty or has only one node 18 | } 19 | 20 | Node *slow = head, *fast = head; 21 | 22 | // Step 1: Detect Loop using Floyd's Cycle Detection Algorithm 23 | while (fast && fast->next) { 24 | slow = slow->next; // Move slow pointer by 1 25 | fast = fast->next->next; // Move fast pointer by 2 26 | 27 | if (slow == fast) { 28 | break; // Loop detected 29 | } 30 | } 31 | 32 | // No loop found 33 | if (slow != fast) { 34 | return; 35 | } 36 | 37 | // Step 2: Find the starting point of the loop 38 | slow = head; 39 | Node* prev = nullptr; // To keep track of the last node before the loop starts 40 | while (slow != fast) { 41 | prev = fast; 42 | slow = slow->next; 43 | fast = fast->next; 44 | } 45 | 46 | // Step 3: Remove the loop 47 | prev->next = nullptr; // Break the loop by setting the next of the last node to null 48 | } 49 | 50 | // Helper function to insert a node at the end of the linked list 51 | void insertNode(Node*& head, int data) { 52 | Node* newNode = new Node(data); 53 | if (!head) { 54 | head = newNode; 55 | return; 56 | } 57 | 58 | Node* temp = head; 59 | while (temp->next) { 60 | temp = temp->next; 61 | } 62 | temp->next = newNode; 63 | } 64 | 65 | // Helper function to print the linked list 66 | void printList(Node* head) { 67 | Node* temp = head; 68 | while (temp) { 69 | cout << temp->data << " "; 70 | temp = temp->next; 71 | } 72 | cout << endl; 73 | } 74 | 75 | // Test code 76 | int main() { 77 | Node* head = nullptr; 78 | 79 | // Creating a linked list: 1 -> 2 -> 3 -> 4 -> 5 80 | insertNode(head, 1); 81 | insertNode(head, 2); 82 | insertNode(head, 3); 83 | insertNode(head, 4); 84 | insertNode(head, 5); 85 | 86 | // Creating a loop: 5 -> 3 (making the next of 5 as 3) 87 | head->next->next->next->next->next = head->next->next; 88 | 89 | detectAndRemoveLoop(head); // Detect and remove the loop 90 | 91 | // Print the list after loop removal 92 | printList(head); // Output should be 1 2 3 4 5 93 | 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /Linked Lists/Flatten_Linked_List.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Node { 5 | public: 6 | int data; 7 | Node* next; 8 | Node* bottom; 9 | 10 | Node(int value) : data(value), next(nullptr), bottom(nullptr) {} 11 | }; 12 | 13 | Node* merge(Node* a, Node* b) { 14 | if (a == nullptr) return b; 15 | if (b == nullptr) return a; 16 | 17 | Node* result; 18 | 19 | if (a->data < b->data) { 20 | result = a; 21 | result->bottom = merge(a->bottom, b); 22 | } else { 23 | result = b; 24 | result->bottom = merge(a, b->bottom); 25 | } 26 | 27 | return result; 28 | } 29 | 30 | Node* flatten(Node* root) { 31 | if (root == nullptr || root->next == nullptr) { 32 | return root; 33 | } 34 | root->next = flatten(root->next); 35 | 36 | root = merge(root, root->next); 37 | 38 | return root; 39 | } 40 | 41 | void printList(Node* node) { 42 | while (node != nullptr) { 43 | cout << node->data << " "; 44 | node = node->bottom; 45 | } 46 | cout << endl; 47 | } 48 | 49 | int main() { 50 | Node* head = new Node(5); 51 | head->next = new Node(10); 52 | head->next->next = new Node(19); 53 | head->next->next->next = new Node(28); 54 | 55 | head->bottom = new Node(7); 56 | head->bottom->bottom = new Node(8); 57 | head->bottom->bottom->bottom = new Node(30); 58 | 59 | head->next->bottom = new Node(20); 60 | 61 | head->next->next->bottom = new Node(22); 62 | head->next->next->bottom->bottom = new Node(50); 63 | 64 | Node* flattened = flatten(head); 65 | 66 | cout << "Flattened Linked List:" << endl; 67 | printList(flattened); 68 | 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /Linked Lists/Reverse-Linked-List.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | class Node { 6 | public: 7 | int data; 8 | Node* next; 9 | Node(int val) : data(val), next(nullptr) {} 10 | }; 11 | 12 | Node* reverseLinkedList(Node* head) { 13 | Node* prev = nullptr; 14 | Node* curr = head; 15 | 16 | while (curr != nullptr) { 17 | Node* nextNode = curr->next; 18 | curr->next = prev; 19 | prev = curr; 20 | curr = nextNode; 21 | } 22 | 23 | return prev; 24 | } 25 | 26 | void printLinkedList(Node* head) { 27 | Node* temp = head; 28 | while (temp != nullptr) { 29 | cout << temp->data << " "; 30 | temp = temp->next; 31 | } 32 | cout << endl; 33 | } 34 | 35 | int main() { 36 | Node* head = new Node(1); 37 | head->next = new Node(2); 38 | head->next->next = new Node(3); 39 | head->next->next->next = new Node(4); 40 | head->next->next->next->next = new Node(5); 41 | 42 | Node* reversedHead = reverseLinkedList(head); 43 | 44 | printLinkedList(reversedHead); 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /Linked Lists/find-cycle-in-linked-list.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class node { 5 | public: 6 | int num; 7 | node* next; 8 | node(int val) { 9 | num = val; 10 | next = NULL; 11 | } 12 | }; 13 | 14 | //utility function to insert node in the list 15 | void insertNode(node* &head,int val) { 16 | node* newNode = new node(val); 17 | 18 | if(head == NULL) { 19 | head = newNode; 20 | return; 21 | } 22 | 23 | node* temp = head; 24 | while(temp->next != NULL) temp = temp->next; 25 | 26 | temp->next = newNode; 27 | return; 28 | } 29 | 30 | //utility function to create cycle 31 | void createCycle(node* &head,int a,int b) { 32 | int cnta = 0,cntb = 0; 33 | node* p1 = head; 34 | node* p2 = head; 35 | while(cnta != a || cntb != b) { 36 | if(cnta != a) p1 = p1->next, ++cnta; 37 | if(cntb != b) p2 = p2->next, ++cntb; 38 | } 39 | p2->next = p1; 40 | } 41 | 42 | //utility function to detect cycle 43 | bool cycleDetect(node* head) { 44 | if(head == NULL) return false; 45 | node* fast = head; 46 | node* slow = head; 47 | 48 | while(fast->next != NULL && fast->next->next != NULL) { 49 | fast = fast->next->next; 50 | slow = slow->next; 51 | if(fast == slow) return true; 52 | } 53 | return false; 54 | } 55 | 56 | 57 | int main() { 58 | node* head = NULL; 59 | insertNode(head,1); 60 | insertNode(head,2); 61 | insertNode(head,3); 62 | insertNode(head,4); 63 | createCycle(head,1,3);//creating cycle in the list 64 | if(cycleDetect(head) == true) 65 | cout<<"Cycle detected\n"; 66 | else 67 | cout<<"Cycle not detected\n"; 68 | return 0; 69 | } -------------------------------------------------------------------------------- /Queues/Circular_queue.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class CircularQueue { 5 | private: 6 | int front, rear, maxSize; 7 | int *arr; 8 | 9 | public: 10 | CircularQueue(int size) { 11 | maxSize = size + 1; 12 | arr = new int[maxSize]; 13 | front = rear = 0; 14 | } 15 | 16 | ~CircularQueue() { 17 | delete[] arr; 18 | } 19 | 20 | bool isEmpty() { 21 | return front == rear; 22 | } 23 | 24 | bool isFull() { 25 | return (rear + 1) % maxSize == front; 26 | } 27 | 28 | void enqueue(int item) { 29 | if (!isFull()) { 30 | rear = (rear + 1) % maxSize; 31 | arr[rear] = item; 32 | } else { 33 | cout << "Queue is full. Cannot enqueue." << endl; 34 | } 35 | } 36 | 37 | void dequeue() { 38 | if (!isEmpty()) { 39 | front = (front + 1) % maxSize; 40 | } else { 41 | cout << "Queue is empty. Cannot dequeue." << endl; 42 | } 43 | } 44 | 45 | void display() { 46 | int i = (front + 1) % maxSize; 47 | cout << "Queue: "; 48 | while (i != (rear + 1) % maxSize) { 49 | cout << arr[i] << " "; 50 | i = (i + 1) % maxSize; 51 | } 52 | cout << endl; 53 | } 54 | }; 55 | 56 | int main() { 57 | CircularQueue cq(5); 58 | 59 | cq.enqueue(1); 60 | cq.enqueue(2); 61 | cq.enqueue(3); 62 | cq.display(); 63 | 64 | cq.dequeue(); 65 | cq.display(); 66 | 67 | cq.enqueue(4); 68 | cq.enqueue(5); 69 | cq.display(); 70 | 71 | cq.enqueue(6); 72 | cq.dequeue(); 73 | cq.dequeue(); 74 | cq.dequeue(); 75 | cq.dequeue(); 76 | cq.display(); 77 | 78 | return 0; 79 | } 80 | Enter 81 | -------------------------------------------------------------------------------- /Queues/Implementation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class Queue { 5 | public: 6 | int front, rear, size; 7 | unsigned capacity; 8 | int* array; 9 | }; 10 | 11 | Queue* createQueue(unsigned capacity) { 12 | Queue* queue = new Queue(); 13 | queue->capacity = capacity; 14 | queue->front = queue->size = 0; 15 | queue->rear = capacity - 1; 16 | queue->array = new int[queue->capacity]; 17 | return queue; 18 | } 19 | 20 | int isFull(Queue* queue) { 21 | return (queue->size == queue->capacity); 22 | } 23 | 24 | int isEmpty(Queue* queue) { 25 | return (queue->size == 0); 26 | } 27 | 28 | void enqueue(Queue* queue, int item) { 29 | if (isFull(queue)) 30 | return; 31 | queue->rear = (queue->rear + 1) % queue->capacity; 32 | queue->array[queue->rear] = item; 33 | queue->size = queue->size + 1; 34 | } 35 | 36 | int dequeue(Queue* queue) { 37 | if (isEmpty(queue)) 38 | return INT_MIN; 39 | int item = queue->array[queue->front]; 40 | queue->front = (queue->front + 1) % queue->capacity; 41 | queue->size = queue->size - 1; 42 | return item; 43 | } 44 | 45 | int front(Queue* queue) { 46 | if (isEmpty(queue)) 47 | return INT_MIN; 48 | return queue->array[queue->front]; 49 | } 50 | 51 | int rear(Queue* queue) { 52 | if (isEmpty(queue)) 53 | return INT_MIN; 54 | return queue->array[queue->rear]; 55 | } 56 | 57 | int main() { 58 | Queue* queue = createQueue(1000); 59 | 60 | enqueue(queue, 10); 61 | enqueue(queue, 20); 62 | enqueue(queue, 30); 63 | enqueue(queue, 40); 64 | 65 | cout << dequeue(queue) << " dequeued from queue\n"; 66 | 67 | cout << "Front item is " << front(queue) << endl; 68 | cout << "Rear item is " << rear(queue) << endl; 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /Queues/LRU_Cache.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | class LRUCache { 6 | private: 7 | int capacity; 8 | std::unordered_map::iterator>> cacheMap; 9 | std::queue keysQueue; 10 | 11 | public: 12 | LRUCache(int capacity) : capacity(capacity) {} 13 | 14 | int get(int key) { 15 | auto it = cacheMap.find(key); 16 | 17 | if (it != cacheMap.end()) { 18 | keysQueue.push(key); 19 | keysQueue.erase(it->second.second); 20 | it->second.second = keysQueue.end() - 1; 21 | return it->second.first; 22 | } 23 | 24 | return -1; 25 | } 26 | 27 | void put(int key, int value) { 28 | auto it = cacheMap.find(key); 29 | 30 | if (it != cacheMap.end()) { 31 | it->second.first = value; 32 | keysQueue.push(key); 33 | keysQueue.erase(it->second.second); 34 | it->second.second = keysQueue.end() - 1; 35 | } else { 36 | if (cacheMap.size() >= capacity) { 37 | int evictedKey = keysQueue.front(); 38 | cacheMap.erase(evictedKey); 39 | keysQueue.pop(); 40 | } 41 | 42 | keysQueue.push(key); 43 | auto iterator = keysQueue.end() - 1; 44 | cacheMap[key] = {value, iterator}; 45 | } 46 | } 47 | }; 48 | 49 | int main() { 50 | LRUCache lruCache(2); 51 | 52 | lruCache.put(1, 1); 53 | lruCache.put(2, 2); 54 | 55 | std::cout << lruCache.get(1) << std::endl; 56 | 57 | lruCache.put(3, 3); 58 | 59 | std::cout << lruCache.get(2) << std::endl; 60 | std::cout << lruCache.get(3) << std::endl; 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /Queues/Reverse_first_k_elements.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | void reverseFirstKElements(queue& q, int k) { 8 | stack s; 9 | for (int i = 0; i < k; ++i) { 10 | s.push(q.front()); 11 | q.pop(); 12 | } 13 | while (!s.empty()) { 14 | q.push(s.top()); 15 | s.pop(); 16 | } 17 | for (int i = 0; i < q.size() - k; ++i) { 18 | q.push(q.front()); 19 | q.pop(); 20 | } 21 | } 22 | 23 | int main() { 24 | queue q; 25 | for (int i = 1; i <= 5; ++i) { 26 | q.push(i); 27 | } 28 | while (!q.empty()) { 29 | cout << q.front() << " "; 30 | q.pop(); 31 | } 32 | cout << endl; 33 | 34 | for (int i = 1; i <= 5; ++i) { 35 | q.push(i); 36 | } 37 | 38 | int k = 3; 39 | reverseFirstKElements(q, k); 40 | 41 | while (!q.empty()) { 42 | cout << q.front() << " "; 43 | q.pop(); 44 | } 45 | cout << endl; 46 | 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /Queues/Stack_using_queues.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | class StackUsingQueues { 7 | private: 8 | queue q1, q2; 9 | 10 | public: 11 | void push(int value) { 12 | q2.push(value); 13 | while (!q1.empty()) { 14 | q2.push(q1.front()); 15 | q1.pop(); 16 | } 17 | swap(q1, q2); 18 | } 19 | 20 | void pop() { 21 | if (!q1.empty()) { 22 | q1.pop(); 23 | } 24 | } 25 | 26 | int top() { 27 | if (!q1.empty()) { 28 | return q1.front(); 29 | } 30 | return -1; // Assuming stack is not empty 31 | } 32 | 33 | bool empty() { 34 | return q1.empty(); 35 | } 36 | }; 37 | 38 | int main() { 39 | StackUsingQueues stack; 40 | 41 | stack.push(1); 42 | stack.push(2); 43 | stack.push(3); 44 | 45 | cout << "Top element: " << stack.top() << endl; 46 | 47 | stack.pop(); 48 | cout << "Top element after pop: " << stack.top() << endl; 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🚀 C++ Algorithms and Codes Repository 2 | 3 | Welcome to the C++ Algorithms and Codes Repository! We invite you to join our community and contribute to this open-source project. Together, we can build a valuable resource for C++ enthusiasts. 4 | 5 | ## 🤝 How to Contribute 6 | 7 | We appreciate your contributions, and here's how you can get started: 8 | 9 | 1. **Fork and Star**: Begin by forking the repository and giving it a star to show your support. 10 | 11 | 2. **Make Changes**: Implement changes in the existing codes or add new codes in C++. 12 | 13 | 3. **Open a Pull Request (PR)**: Create a PR to share your work with the community. 14 | 15 | 4. **Contribution Details**: In your PR, describe the changes you've made or the features you've added. Help us understand why they are valuable. 16 | 17 | ## 🔍 Contribution Guidelines 18 | 19 | To ensure a smooth and productive collaboration, please keep these guidelines in mind: 20 | 21 | - 💡 Ensure your code is well-documented with clear explanations and comments. 22 | 23 | - 🧰 Write in modern C++ and follow best practices. 24 | 25 | - 🧐 Adhere to our code style and formatting guidelines. 26 | 27 | - 🧪 Test your code to prevent introducing bugs. Provide test cases when relevant. 28 | 29 | - 🙏 Respect other contributors' opinions and ideas. Be polite and professional in all interactions. 30 | 31 | We appreciate your efforts in making this repository a great resource for everyone. Please refrain from spamming and maintain a respectful and collaborative environment. 32 | 33 | You can follow me at [@prabhjotschugh](https://github.com/prabhjotschugh) 34 | 35 | Thank you for contributing! 🙌 36 | -------------------------------------------------------------------------------- /Recursion/Kth_symbol_in_grammar.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int kthGrammar(int N, int K) { 5 | if (N == 1) return 0; 6 | int parent = kthGrammar(N - 1, (K + 1) / 2); 7 | if (K % 2 == 1) { 8 | return parent; 9 | } else { 10 | return 1 - parent; 11 | } 12 | } 13 | 14 | int main() { 15 | int N = 4; // Example value for N 16 | int K = 5; // Example value for K 17 | cout << "The K-th symbol in grammar is: " << kthGrammar(N, K) << endl; 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /Recursion/N_Queens.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | bool isSafe(int board[][100], int i, int j, int n) 5 | { 6 | for (int k = 0; k < n; k++) 7 | { 8 | if (board[k][j] == 1) 9 | { 10 | return false; 11 | } 12 | if (board[i][k] == 1) 13 | { 14 | return false; 15 | } 16 | } 17 | int l = i, m = j; 18 | while (l >= 0 and m >= 0) 19 | { 20 | if (board[l][m] == 1) 21 | { 22 | return false; 23 | } 24 | l--; 25 | m--; 26 | } 27 | while (i >= 0 and j < n) 28 | { 29 | if (board[i][j] == 1) 30 | { 31 | return false; 32 | } 33 | i--; 34 | j++; 35 | } 36 | return true; 37 | } 38 | int ans=0; 39 | bool NQueen(int board[][100], int i, int n) 40 | { 41 | // base case 42 | if (i == n) 43 | { 44 | ans++; 45 | // for (int i = 0; i < n; i++) 46 | // { 47 | // for (int j = 0; j < n; j++) 48 | // { 49 | // // board[i][j] == 1 ? cout << "Q" : cout << "_"; 50 | // } 51 | // cout << endl; 52 | // } 53 | return false; 54 | } 55 | // recursive case 56 | 57 | // Har column par jao 58 | for (int j = 0; j < n; j++) 59 | { 60 | if (isSafe(board, i, j, n)) 61 | { 62 | board[i][j] = 1; 63 | bool baakisafe; 64 | baakisafe = NQueen(board, i + 1, n); 65 | if (baakisafe == true) 66 | return true; 67 | board[i][j] = 0; 68 | } 69 | } 70 | return false; 71 | } 72 | int main() 73 | { 74 | int board[100][100]; 75 | int n; 76 | cin >> n; 77 | NQueen(board, 0, n); 78 | cout< 2 | #include 3 | using namespace std; 4 | bool isSafe(int board[][9], int i, int j, int no, int n) 5 | { 6 | // row and col mai nhi hona chahiye 7 | for (int k = 0; k < n; k++) 8 | { 9 | if (board[i][k] == no || board[k][j] == no) 10 | { 11 | return false; 12 | } 13 | } 14 | 15 | // daba checking idhar hogi 16 | n = sqrt(n); 17 | int si = (i / n) * n; 18 | int sj = (j / n) * n; 19 | for (int k = si; k < si + n; k++) 20 | { 21 | for (int l = sj; l < sj + n; l++) 22 | { 23 | if (board[k][l] == no) 24 | { 25 | return false; 26 | } 27 | } 28 | } 29 | return true; 30 | } 31 | bool SudokuSolver(int board[][9], int i, int j, int n) 32 | { 33 | // base case 34 | if (i == n) 35 | { 36 | for (int l = 0; l < 9; l++) 37 | { 38 | for (int m = 0; m < 9; m++) 39 | { 40 | cout << board[l][m] << " "; 41 | } 42 | cout << endl; 43 | } 44 | return true; 45 | } 46 | // recursive case 47 | if (j == n) 48 | { 49 | return SudokuSolver(board, i + 1, 0, n); // agar column n pee pohoch jaye toh niche kaar doo 50 | } 51 | if (board[i][j] != 0) 52 | { 53 | return SudokuSolver(board, i, j + 1, n); 54 | } 55 | for (int no = 1; no < 10; no++) 56 | { 57 | if (isSafe(board, i, j, no, n)) 58 | { 59 | board[i][j] = no; 60 | bool baakisolve = SudokuSolver(board, i, j + 1, n); 61 | if (baakisolve) 62 | { 63 | return true; 64 | } 65 | board[i][j] = 0; 66 | } 67 | } 68 | return false; 69 | } 70 | int main() 71 | { 72 | int sudoku[9][9] = { 73 | {3, 0, 6, 5, 0, 8, 4, 0, 0}, 74 | {5, 2, 0, 0, 0, 0, 0, 0, 0}, 75 | {0, 8, 7, 0, 0, 0, 0, 3, 1}, 76 | {0, 0, 3, 0, 1, 0, 0, 8, 0}, 77 | {9, 0, 0, 8, 6, 3, 0, 0, 5}, 78 | {0, 5, 0, 0, 9, 0, 6, 0, 0}, 79 | {1, 3, 0, 0, 0, 0, 2, 5, 0}, 80 | {0, 0, 0, 0, 0, 0, 0, 7, 4}, 81 | {0, 0, 5, 2, 0, 6, 3, 0, 0}}; 82 | SudokuSolver(sudoku, 0, 0, 9); 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /Recursion/Tower_of_hanoi.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | void towerOfHanoi(int n, char from_rod, char to_rod, char aux_rod) { 5 | if (n == 1) { 6 | cout << "Move disk 1 from rod " << from_rod << " to rod " << to_rod << endl; 7 | return; 8 | } 9 | towerOfHanoi(n - 1, from_rod, aux_rod, to_rod); 10 | cout << "Move disk " << n << " from rod " << from_rod << " to rod " << to_rod << endl; 11 | towerOfHanoi(n - 1, aux_rod, to_rod, from_rod); 12 | } 13 | 14 | int main() { 15 | int n; 16 | cout << "Enter the number of disks: "; 17 | cin >> n; 18 | towerOfHanoi(n, 'A', 'C', 'B'); 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /Recursion/noOfSubseqwithSumk.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | int subseq(int i,int n,vector&arr,int curr_sum, int k){ 5 | if(i>=n){ 6 | if(curr_sum==k){ 7 | return 1; 8 | } 9 | return 0; 10 | } 11 | curr_sum+=arr[i]; 12 | int l = (subseq(i+1,n,arr,curr_sum,k)); 13 | curr_sum -= arr[i]; 14 | int r = (subseq(i+1,n,arr,curr_sum,k)); 15 | 16 | return l+r; 17 | } 18 | 19 | int main(){ 20 | int n,k; 21 | cin>>n>>k; 22 | vectorvec(n); 23 | for(int i=0; i>vec[i]; 25 | cout< 2 | #include 3 | using namespace std; 4 | 5 | bool isMatch(const string &s, const string &p) { 6 | int m = s.size(), n = p.size(); 7 | vector> dp(m + 1, vector(n + 1, false)); 8 | dp[0][0] = true; 9 | 10 | for (int j = 1; j <= n; ++j) { 11 | if (p[j - 1] == '*') { 12 | dp[0][j] = dp[0][j - 1]; 13 | } 14 | } 15 | 16 | for (int i = 1; i <= m; ++i) { 17 | for (int j = 1; j <= n; ++j) { 18 | if (p[j - 1] == '*') { 19 | dp[i][j] = dp[i][j - 1] || dp[i - 1][j]; 20 | } else if (p[j - 1] == '?' || s[i - 1] == p[j - 1]) { 21 | dp[i][j] = dp[i - 1][j - 1]; 22 | } 23 | } 24 | } 25 | 26 | return dp[m][n]; 27 | } 28 | 29 | int main() { 30 | string s, p; 31 | cout << "Enter the string: "; 32 | cin >> s; 33 | cout << "Enter the pattern: "; 34 | cin >> p; 35 | if (isMatch(s, p)) { 36 | cout << "The pattern matches the string." << endl; 37 | } else { 38 | cout << "The pattern does not match the string." << endl; 39 | } 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /Sorting/1_selection-sort.cpp: -------------------------------------------------------------------------------- 1 | // Selection Sort --> T.C: worst, best and avg - O(n^2) , S.C: O(1) ; where n = size of the array 2 | // Inplace but not stable. 3 | // Select the minimum element and swap it with the leftmost element. 4 | 5 | // For no. of elements in array = n, 6 | // swap at index 0 and min of index (0, n-1) 7 | // swap at index 1 and min of index (1, n-1) 8 | // swap at index 2 and min of index (2, n-1) ... 9 | 10 | // swap at index n-2 and min of index (n-2,n-1) 11 | 12 | #include 13 | using namespace std; 14 | 15 | void selectionSort(vector &v){ 16 | int n = v.size(); 17 | 18 | for (int i = 0; i < n-1; i++) { 19 | int minIndex = i; // Index of the minimum element 20 | for (int j = i+1; j < n; j++) { 21 | if (v[j] < v[minIndex]) 22 | minIndex = j; 23 | } 24 | swap(v[i], v[minIndex]); // Swap the minimum element with the current position 25 | 26 | // int temp = v[minIndex]; 27 | // v[minIndex] = v[i]; 28 | // v[i] = temp; 29 | } 30 | } 31 | 32 | int main(){ 33 | vector nums = {13, 46, 24, 52, 50, 9}; 34 | 35 | selectionSort(nums); 36 | 37 | for (auto i : nums){ 38 | cout << i << " "; 39 | } 40 | 41 | return 0; 42 | } -------------------------------------------------------------------------------- /Sorting/2_bubble-sort.cpp: -------------------------------------------------------------------------------- 1 | // Bubble Sort --> T.C: O(N^2) and best - O(N) , where N = size of the array 2 | // Best case occurs when given array is already sorted 3 | // Pushes the maximum element to the last by adjacent swapping 4 | // For n elements in array, (n-1) iterations are required 5 | 6 | #include 7 | using namespace std; 8 | 9 | void bubbleSort(vector &v){ 10 | int n = v.size(); 11 | for(int i = n-1; i >= 0; i--){ 12 | for(int j = 0; j < i; j++){ 13 | if(v[j+1] < v[j]) 14 | swap(v[j], v[j+1]); 15 | } 16 | } 17 | 18 | } 19 | 20 | void bubbleSort2(vector& v){ // different & better way of writing for-loop 21 | int n = v.size(); 22 | bool didSwap = false; 23 | 24 | for (int i = 0; i < n; i++){ 25 | for (int j = 0; j < n-i; j++){ 26 | if (v[j] > v[j+1]){ 27 | swap(v[j], v[j+1]); 28 | didSwap = true; 29 | } 30 | } 31 | 32 | if(didSwap == false) // if no swapping happens. 33 | break; 34 | } 35 | } 36 | 37 | void recursive_bubble_sort(vector& v, int n){ // S.C: O(N) auxiliary stack space, T.C: same as iterative bubble sort. 38 | if (n == 1) // Base Case: range == 1. 39 | return; 40 | 41 | bool didSwap = false; 42 | 43 | for (int i = 0; i <= n-2; i++) { 44 | if (v[i] > v[i+1]){ 45 | swap(v[i], v[i+1]); 46 | didSwap = true; 47 | } 48 | } 49 | 50 | if(didSwap == false) // if no swapping happens. 51 | return; 52 | 53 | recursive_bubble_sort(v, n-1); // Range reduced after recursion: 54 | } 55 | 56 | 57 | int main(){ 58 | vector nums = {13, 46, 24, 52, 50, 9}; 59 | 60 | // bubbleSort(nums); 61 | 62 | bubbleSort2(nums); 63 | 64 | // int n = nums.size(); 65 | // recursive_bubble_sort(nums, n); 66 | 67 | for (auto i : nums){ 68 | cout << i << " "; 69 | } 70 | 71 | return 0; 72 | } -------------------------------------------------------------------------------- /Sorting/3_insertion-sort.cpp: -------------------------------------------------------------------------------- 1 | // Insertion Sort --> T.C: O(N^2) and best - O(N) , where N = size of the array 2 | // Best case occurs when array is already sorted becacue the inner while loop will never run then. 3 | // Take an element and place it in its correct order. 4 | 5 | #include 6 | using namespace std; 7 | 8 | void insertionSort(vector &v){ 9 | int n = v.size(); 10 | for(int i = 0; i < n; i++){ 11 | int j = i; 12 | while(j > 0 && v[j-1] > v[j]){ 13 | swap(v[j], v[j-1]); 14 | j--; 15 | } 16 | } 17 | 18 | } 19 | 20 | void recursive_insertion_sort(vector &v, int i, int n) { 21 | if (i == n) return; // Base Case: i == n. 22 | 23 | int j = i; 24 | while(j > 0 && v[j-1] > v[j]){ 25 | swap(v[j], v[j-1]); 26 | j--; 27 | } 28 | 29 | recursive_insertion_sort(v, i+1, n); 30 | } 31 | 32 | int main(){ 33 | vector nums = {13, 46, 24, 52, 50, 9}; 34 | 35 | // insertionSort(nums); 36 | 37 | int n = nums.size(); 38 | recursive_insertion_sort(nums, 0, n); 39 | 40 | for (auto i : nums){ 41 | cout << i << " "; 42 | } 43 | 44 | return 0; 45 | } -------------------------------------------------------------------------------- /Sorting/4_merge-sort.cpp: -------------------------------------------------------------------------------- 1 | // Merge Sort --> T.C: Best & worst - O(N*log(N)), S.C: O(N) for temp array; where N = size of the array 2 | // Divide and merge // O(log n) time in dividing and O(n) time in merging back 3 | // Merge sort and quick sort are examples of divide and conquer algorithms. 4 | 5 | #include 6 | using namespace std; 7 | 8 | void merge(vector &v, int low, int mid, int high){ 9 | vector temp; // temporary array 10 | int left = low; // starting index of left half of arr 11 | int right = mid + 1; // starting index of right half of arr 12 | 13 | //storing elements in the temporary array in a sorted manner// 14 | while(left <= mid && right <= high){ 15 | if(v[left] <= v[right]){ 16 | temp.push_back(v[left]); 17 | left++; 18 | } 19 | 20 | else{ 21 | temp.push_back(v[right]); 22 | right++; 23 | } 24 | } 25 | 26 | // if elements on the left half are still left // 27 | while(left <= mid){ 28 | temp.push_back(v[left]); 29 | left++; 30 | } 31 | 32 | // if elements on the right half are still left // 33 | while(right <= high){ 34 | temp.push_back(v[right]); 35 | right++; 36 | } 37 | 38 | // transfering all elements from temporary to arr // 39 | for(int i=low; i <= high; i++){ 40 | v[i] = temp[i - low]; 41 | } 42 | } 43 | 44 | void mergeSort(vector &v, int low, int high){ 45 | if(low >= high) 46 | return; 47 | int mid = (low + high) / 2; 48 | mergeSort(v, low, mid); // left half 49 | mergeSort(v, mid+1, high); // right half 50 | merge(v, low, mid, high); // merging sorted halves 51 | } 52 | 53 | int main(){ 54 | vector nums = {13, 46, 24, 52, 50, 9}; 55 | int n = nums.size(); 56 | 57 | mergeSort(nums, 0, n-1); 58 | 59 | for (auto i : nums){ 60 | cout << i << " "; 61 | } 62 | 63 | return 0; 64 | } -------------------------------------------------------------------------------- /Sorting/5_quick-sort.cpp: -------------------------------------------------------------------------------- 1 | // Quick Sort --> T.C: O(N*log(N)), S.C: O(1) ; where N = size of the array 2 | // The worst case complexity will be O(N^2) if we end up choosing the largest or smallest element as the pivot always. 3 | 4 | // 1) Pick a pivot and place it in its correct place in the sorted array. 2) Then place smaller elements on left and larger on the right. 5 | // Generally, 1st element is selected as pivot and placed in its correct position, but any element can be the pivot. 6 | /* For step 2, set two pointer - i at the pivot and j at the end of array. Then find the first element from left greater than pivot 7 | and first element from right smaller than the pivot, and then swap them. Then i++, j--. Repeat till i 11 | using namespace std; 12 | 13 | int partition(vector &v, int low, int high){ 14 | int pivot = v[low]; 15 | int i = low; 16 | int j = high; 17 | 18 | while(i < j){ 19 | while(v[i] <= pivot && i <= high-1){ 20 | i++; 21 | } 22 | 23 | while(v[j] >= pivot && j >= low+1){ 24 | j--; 25 | } 26 | 27 | if(i < j) 28 | swap(v[i], v[j]); 29 | } 30 | 31 | swap(v[low], v[j]); // j is the partition index and v[low] is the pivot 32 | return j; 33 | } 34 | 35 | void quickSort(vector &v, int low, int high){ 36 | if(low < high){ 37 | int pIndex = partition(v, low, high); 38 | quickSort(v, low, pIndex-1); 39 | quickSort(v, pIndex+1, high); 40 | } 41 | } 42 | 43 | int main(){ 44 | vector nums = {13, 46, 24, 52, 50, 9}; 45 | int n = nums.size(); 46 | 47 | quickSort(nums, 0, n-1); 48 | 49 | for (auto i : nums){ 50 | cout << i << " "; 51 | } 52 | 53 | return 0; 54 | } -------------------------------------------------------------------------------- /Sorting/6_heap-sort.cpp: -------------------------------------------------------------------------------- 1 | // Heap Sort --> T.C: O(N*log(N)) in all cases, S.C: O(1) ; where N = size of the array 2 | 3 | 4 | #include 5 | using namespace std; 6 | 7 | void heapSort(vector &v){ 8 | int n = v.size(); 9 | 10 | 11 | } 12 | 13 | int main(){ 14 | vector nums = {13, 46, 24, 52, 50, 9}; 15 | 16 | heapSort(nums); 17 | 18 | for (auto i : nums){ 19 | cout << i << " "; 20 | } 21 | 22 | return 0; 23 | } -------------------------------------------------------------------------------- /Sorting/7_tim-sort.cpp: -------------------------------------------------------------------------------- 1 | //Tim Sort --> T.C: O(N*log(N)) in all cases, S.C: O(N) ; where N = size of the array 2 | // Tim Sort is a hybrid sorting algorithm derived from merge sort and insertion sort. It was designed to perform well on real-world data. 3 | /* 4 | The algorithm divides the array into small segments called "runs" (typically of size 32). Each run is sorted using insertion sort.The sorted runs are then merged together using a modified merge process, similar to that in merge sort. 5 | */ 6 | 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | const int RUN = 32; 12 | 13 | void insertionSort(vector& arr, int left, int right) { 14 | for (int i = left + 1; i <= right; i++) { 15 | int key = arr[i]; 16 | int j = i - 1; 17 | while (j >= left && arr[j] > key) { 18 | arr[j + 1] = arr[j]; 19 | j--; 20 | } 21 | arr[j + 1] = key; 22 | } 23 | } 24 | 25 | void merge(vector& arr, int left, int mid, int right) { 26 | int len1 = mid - left + 1, len2 = right - mid; 27 | vector leftArr(len1), rightArr(len2); 28 | for (int i = 0; i < len1; i++) 29 | leftArr[i] = arr[left + i]; 30 | for (int i = 0; i < len2; i++) 31 | rightArr[i] = arr[mid + 1 + i]; 32 | 33 | int i = 0, j = 0, k = left; 34 | while (i < len1 && j < len2) { 35 | if (leftArr[i] <= rightArr[j]) 36 | arr[k++] = leftArr[i++]; 37 | else 38 | arr[k++] = rightArr[j++]; 39 | } 40 | while (i < len1) 41 | arr[k++] = leftArr[i++]; 42 | while (j < len2) 43 | arr[k++] = rightArr[j++]; 44 | } 45 | 46 | void timSort(vector& arr) { 47 | int n = arr.size(); 48 | for (int i = 0; i < n; i += RUN) 49 | insertionSort(arr, i, min((i + RUN - 1), (n - 1))); 50 | for (int size = RUN; size < n; size *= 2) { 51 | for (int left = 0; left < n; left += 2 * size) { 52 | int mid = min(left + size - 1, n - 1); 53 | int right = min((left + 2 * size - 1), (n - 1)); 54 | if (mid < right) 55 | merge(arr, left, mid, right); 56 | } 57 | } 58 | } 59 | 60 | int main() { 61 | vector arr = {5, 21, 7, 23, 19}; 62 | timSort(arr); 63 | for (int num : arr) { 64 | cout << num << " "; 65 | } 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /Sorting/8_shell-sort.cpp: -------------------------------------------------------------------------------- 1 | // Shell Sort --> TC: O(n^2), SC: O(1) 2 | /* 3 | Shell Sort is an in-place comparison-based sorting algorithm that generalizes insertion sort to allow the exchange of items that are far apart. 4 | It works by first sorting elements that are far apart from each other, then progressively reducing the gap between the elements to be compared. 5 | */ 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | void shellSort(vector& arr) { 11 | int n = arr.size(); 12 | for (int gap = n / 2; gap > 0; gap /= 2) { 13 | for (int i = gap; i < n; i++) { 14 | int temp = arr[i]; 15 | int j; 16 | for (j = i; j >= gap && arr[j - gap] > temp; j -= gap) { 17 | arr[j] = arr[j - gap]; 18 | } 19 | arr[j] = temp; 20 | } 21 | } 22 | } 23 | 24 | int main() { 25 | vector arr = {12, 34, 54, 2, 3}; 26 | shellSort(arr); 27 | for (int num : arr) { 28 | cout << num << " "; 29 | } 30 | return 0; 31 | } -------------------------------------------------------------------------------- /Sorting/9_inplace-merge-sort.cpp: -------------------------------------------------------------------------------- 1 | //In-Place Merge Sort --> TC: O(n^2), SC: O(1) 2 | /* 3 | Unlike the standard merge sort, which uses O(n) additional space, the in-place version reduces the auxiliary space complexity to O(1) for the merging process, making it more memory-efficient. 4 | It retains the advantages of the divide-and-conquer strategy, making it efficient for large datasets with a time complexity of O(n log n) in all cases (best, average, and worst). 5 | In-place merge sort can be beneficial for large datasets where memory usage is a concern, particularly when dealing with large arrays in environments with limited memory. 6 | */ 7 | #include 8 | #include 9 | using namespace std; 10 | 11 | void merge(vector& arr, int left, int mid, int right) { 12 | int start2 = mid + 1; 13 | 14 | // If the direct merge is already sorted 15 | if (arr[mid] <= arr[start2]) return; 16 | 17 | // Two pointers to maintain start of both subarrays 18 | while (left <= mid && start2 <= right) { 19 | if (arr[left] <= arr[start2]) { 20 | left++; 21 | } else { 22 | int value = arr[start2]; 23 | int index = start2; 24 | 25 | // Shift all elements between left and start2 right by 1 26 | while (index != left) { 27 | arr[index] = arr[index - 1]; 28 | index--; 29 | } 30 | arr[left] = value; 31 | 32 | // Update all pointers 33 | left++; 34 | mid++; 35 | start2++; 36 | } 37 | } 38 | } 39 | 40 | void inPlaceMergeSort(vector& arr, int left, int right) { 41 | if (left < right) { 42 | int mid = left + (right - left) / 2; 43 | 44 | inPlaceMergeSort(arr, left, mid); 45 | inPlaceMergeSort(arr, mid + 1, right); 46 | merge(arr, left, mid, right); 47 | } 48 | } 49 | 50 | int main() { 51 | vector arr = {12, 11, 13, 5, 6, 7}; 52 | int n = arr.size(); 53 | inPlaceMergeSort(arr, 0, n - 1); 54 | 55 | for (int num : arr) { 56 | cout << num << " "; 57 | } 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /Sorting/Dutch_national_flag.cpp: -------------------------------------------------------------------------------- 1 | // sort array of 0s, 1s and 2s 2 | #include 3 | using namespace std; 4 | void sort012(int a[], int arr_size) 5 | { 6 | int low = 0; 7 | int high = arr_size - 1; 8 | int mid = 0; 9 | 10 | while (mid <= high) 11 | { 12 | if (a[mid] == 0) 13 | { 14 | swap(a[low++], a[mid++]); 15 | } 16 | 17 | else if (a[mid] == 1) 18 | { 19 | mid++; 20 | } 21 | 22 | else 23 | { 24 | swap(a[mid], a[high--]); 25 | } 26 | } 27 | } 28 | 29 | void printArray(int arr[], int arr_size) 30 | { 31 | for (int i = 0; i < arr_size; i++) 32 | cout << arr[i] << " "; 33 | } 34 | 35 | int main() 36 | { 37 | int arr[] = {0, 1, 1, 0, 1, 2, 1, 2, 0, 0, 0, 1}; 38 | int n = sizeof(arr) / sizeof(arr[0]); 39 | 40 | sort012(arr, n); 41 | 42 | printArray(arr, n); 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /Sorting/Radix_Sort.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | int getMax(vector& arr) { 7 | int max = arr[0]; 8 | for (int i = 1; i < arr.size(); i++) 9 | if (arr[i] > max) 10 | max = arr[i]; 11 | return max; 12 | } 13 | 14 | void countingSort(vector& arr, int exp) { 15 | const int n = arr.size(); 16 | vector output(n, 0); 17 | vector count(10, 0); 18 | 19 | for (int i = 0; i < n; i++) 20 | count[(arr[i] / exp) % 10]++; 21 | 22 | for (int i = 1; i < 10; i++) 23 | count[i] += count[i - 1]; 24 | 25 | for (int i = n - 1; i >= 0; i--) { 26 | output[count[(arr[i] / exp) % 10] - 1] = arr[i]; 27 | count[(arr[i] / exp) % 10]--; 28 | } 29 | 30 | for (int i = 0; i < n; i++) 31 | arr[i] = output[i]; 32 | } 33 | 34 | void radixSort(vector& arr) { 35 | int max = getMax(arr); 36 | 37 | for (int exp = 1; max / exp > 0; exp *= 10) 38 | countingSort(arr, exp); 39 | } 40 | 41 | void printArray(vector& arr) { 42 | for (int i = 0; i < arr.size(); i++) 43 | cout << arr[i] << " "; 44 | cout << endl; 45 | } 46 | 47 | int main() { 48 | vector arr = {170, 45, 75, 90, 802, 24, 2, 66}; 49 | int n = arr.size(); 50 | 51 | cout << "Original array: "; 52 | printArray(arr); 53 | 54 | radixSort(arr); 55 | 56 | cout << "Sorted array: "; 57 | printArray(arr); 58 | 59 | return 0; 60 | } 61 | Enter 62 | -------------------------------------------------------------------------------- /Stacks/Asteroid_collision.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | vector asteroidCollision(vector& asteroids) { 7 | stack s; 8 | for (int asteroid : asteroids) { 9 | bool destroyed = false; 10 | while (!s.empty() && asteroid < 0 && s.top() > 0) { 11 | if (s.top() < -asteroid) { 12 | s.pop(); 13 | continue; 14 | } else if (s.top() == -asteroid) { 15 | s.pop(); 16 | } 17 | destroyed = true; 18 | break; 19 | } 20 | if (!destroyed) { 21 | s.push(asteroid); 22 | } 23 | } 24 | vector result; 25 | while (!s.empty()) { 26 | result.push_back(s.top()); 27 | s.pop(); 28 | } 29 | reverse(result.begin(), result.end()); 30 | return result; 31 | } 32 | 33 | int main() { 34 | vector asteroids = {5, 10, -5}; 35 | vector result = asteroidCollision(asteroids); 36 | for (int asteroid : result) { 37 | cout << asteroid << " "; 38 | } 39 | cout << endl; 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /Stacks/Balanced-Parenthesis.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | bool isBalanced(string expression) { 8 | stack s; 9 | for (char bracket : expression) { 10 | if (bracket == '(' || bracket == '[' || bracket == '{') { 11 | s.push(bracket); 12 | } else if (!s.empty() && 13 | ((bracket == ')' && s.top() == '(') || 14 | (bracket == ']' && s.top() == '[') || 15 | (bracket == '}' && s.top() == '{'))) { 16 | s.pop(); 17 | } else { 18 | return false; 19 | } 20 | } 21 | return s.empty(); 22 | } 23 | 24 | int main() { 25 | string expression = "{[()]}"; 26 | bool balanced = isBalanced(expression); 27 | if (balanced) { 28 | cout << "The expression is balanced." << endl; 29 | } else { 30 | cout << "The expression is not balanced." << endl; 31 | } 32 | return 0; 33 | } 34 | -------------------------------------------------------------------------------- /Stacks/Maximum_area_histogram.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | int largestRectangleArea(vector& heights) { 8 | stack s; 9 | int maxArea = 0; 10 | 11 | for (int i = 0; i <= heights.size(); ++i) { 12 | while (!s.empty() && (i == heights.size() || heights[i] < heights[s.top()])) { 13 | int h = heights[s.top()]; 14 | s.pop(); 15 | int w = s.empty() ? i : i - s.top() - 1; 16 | maxArea = max(maxArea, h * w); 17 | } 18 | s.push(i); 19 | } 20 | 21 | return maxArea; 22 | } 23 | 24 | int main() { 25 | vector heights = {2, 1, 5, 6, 2, 3}; 26 | int result = largestRectangleArea(heights); 27 | 28 | cout << "Maximum area of the histogram: " << result << endl; 29 | 30 | return 0; 31 | } 32 | Enter 33 | -------------------------------------------------------------------------------- /Stacks/Stack-Implementation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | class Stack 6 | { 7 | public: 8 | int data; 9 | listst; 10 | Stack() 11 | { 12 | 13 | } 14 | int push(int data) 15 | { 16 | this->data = data; 17 | st.push_back(data); 18 | return data; 19 | } 20 | bool isEmpty() 21 | { 22 | if(st.empty()) 23 | { 24 | return true; 25 | } 26 | else 27 | { 28 | return false; 29 | } 30 | } 31 | int peek() 32 | { 33 | return st.back(); 34 | } 35 | int pop() 36 | { 37 | int element = st.back(); 38 | st.pop_back(); 39 | return element; 40 | } 41 | int size() 42 | { 43 | return st.size(); 44 | } 45 | }; 46 | 47 | int main() 48 | { 49 | Stack s; 50 | cout << "Is empty " << s.isEmpty() << endl; 51 | s.push(4); 52 | cout << "First Element " << s.peek() << endl; 53 | cout << "Is empty " << s.isEmpty() << endl; 54 | } 55 | -------------------------------------------------------------------------------- /Stacks/Trapping_rainwater.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | int trap(vector& height) { 7 | int n = height.size(), waterTrapped = 0; 8 | stack s; 9 | 10 | for (int i = 0; i < n; i++) { 11 | while (!s.empty() && height[i] > height[s.top()]) { 12 | int top = s.top(); 13 | s.pop(); 14 | if (s.empty()) break; 15 | int distance = i - s.top() - 1; 16 | int boundedHeight = min(height[i], height[s.top()]) - height[top]; 17 | waterTrapped += distance * boundedHeight; 18 | } 19 | s.push(i); 20 | } 21 | return waterTrapped; 22 | } 23 | 24 | int main() { 25 | vector height = {0,1,0,2,1,0,1,3,2,1,2,1}; 26 | cout << trap(height) << endl; 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /Trees/AVL_Trees_Implementation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | class Node { 5 | public: 6 | int key; 7 | Node* left; 8 | Node* right; 9 | int height; 10 | 11 | Node(int k) : key(k), left(nullptr), right(nullptr), height(1) {} 12 | }; 13 | 14 | class AVLTree { 15 | private: 16 | Node* root; 17 | 18 | int getHeight(Node* node) { 19 | if (node == nullptr) 20 | return 0; 21 | return node->height; 22 | } 23 | 24 | int getBalanceFactor(Node* node) { 25 | if (node == nullptr) 26 | return 0; 27 | return getHeight(node->left) - getHeight(node->right); 28 | } 29 | 30 | Node* rightRotate(Node* y) { 31 | Node* x = y->left; 32 | Node* T2 = x->right; 33 | 34 | x->right = y; 35 | y->left = T2; 36 | 37 | y->height = std::max(getHeight(y->left), getHeight(y->right)) + 1; 38 | x->height = std::max(getHeight(x->left), getHeight(x->right)) + 1; 39 | 40 | return x; 41 | } 42 | 43 | Node* leftRotate(Node* x) { 44 | Node* y = x->right; 45 | Node* T2 = y->left; 46 | 47 | y->left = x; 48 | x->right = T2; 49 | #include 50 | #include 51 | 52 | class Node { 53 | public: 54 | int key; 55 | Node* left; 56 | Node* right; 57 | int height; 58 | 59 | Node(int k) : key(k), left(nullptr), right(nullptr), height(1) {} 60 | }; 61 | 62 | class AVLTree { 63 | private: 64 | Node* root; 65 | 66 | int getHeight(Node* node) { 67 | if (node == nullptr) 68 | return 0; 69 | return node->height; 70 | } 71 | 72 | int getBalanceFactor(Node* node) { 73 | if (node == nullptr) 74 | return 0; 75 | return getHeight(node->left) - getHeight(node->right); 76 | } 77 | 78 | Node* rightRotate(Node* y) { 79 | Node* x = y->left; 80 | Node* T2 = x->right; 81 | 82 | x->right = y; 83 | y->left = T2; 84 | 85 | y->height = std::max(getHeight(y->left), getHeight(y->right)) + 1; 86 | x->height = std::max(getHeight(x->left), getHeight(x->right)) + 1; 87 | 88 | return x; 89 | } 90 | 91 | Node* leftRotate(Node* x) { 92 | Node* y = x->right; 93 | Node* T2 = y->left; 94 | 95 | y->left = x; 96 | x->right = T2; 97 | 98 | x->height = std::max(getHeight(x->left), getHeight(x->right)) + 1; 99 | y->height = std::max(getHeight(y->left), getHeight(y->right)) + 1; 100 | 101 | return y; 102 | } 103 | 104 | Node* insert(Node* node, int key) { 105 | if (node == nullptr) 106 | return new Node(key); 107 | 108 | if (key < node->key) 109 | node->left = insert(node->left, key); 110 | else if (key > node->key) 111 | node->right = insert(node->right, key); 112 | else 113 | return node; // Duplicate keys not allowed 114 | 115 | node->height = 1 + std::max(getHeight(node->left), getHeight(node->right)); 116 | 117 | int balance = getBalanceFactor(node); 118 | 119 | // Left-Left case 120 | if (balance > 1 && key < node->left->key) 121 | return rightRotate(node); 122 | 123 | // Right-Right case 124 | if (balance < -1 && key > node->right->key) 125 | return leftRotate(node); 126 | 127 | // Left-Right case 128 | if (balance > 1 && key > node->left->key) { 129 | node->left = leftRotate(node->left); 130 | return rightRotate(node); 131 | } 132 | 133 | // Right-Left case 134 | if (balance < -1 && key < node->right->key) { 135 | node->right = rightRotate(node->right); 136 | return leftRotate(node); 137 | } 138 | 139 | return node; 140 | } 141 | 142 | void inorderTraversal(Node* node) { 143 | if (node != nullptr) { 144 | inorderTraversal(node->left); 145 | std::cout << node->key << " "; 146 | inorderTraversal(node->right); 147 | } 148 | } 149 | 150 | public: 151 | AVLTree() : root(nullptr) {} 152 | 153 | void insert(int key) { 154 | root = insert(root, key); 155 | } 156 | 157 | void printInorder() { 158 | inorderTraversal(root); 159 | std::cout << std::endl; 160 | } 161 | }; 162 | 163 | int main() { 164 | AVLTree avlTree; 165 | 166 | avlTree.insert(10); 167 | avlTree.insert(20); 168 | avlTree.insert(30); 169 | 170 | std::cout << "Inorder traversal of the AVL Tree: "; 171 | avlTree.printInorder(); 172 | 173 | return 0; 174 | } 175 | Enter 176 | x->height = std::max(getHeight(x->left), getHeight(x->right)) + 1; 177 | y->height = std::max(getHeight(y->left), getHeight(y->right)) + 1; 178 | 179 | return y; 180 | } 181 | 182 | Node* insert(Node* node, int key) { 183 | if (node == nullptr) 184 | return new Node(key); 185 | 186 | if (key < node->key) 187 | node->left = insert(node->left, key); 188 | else if (key > node->key) 189 | node->right = insert(node->right, key); 190 | else 191 | return node; // Duplicate keys not allowed 192 | 193 | node->height = 1 + std::max(getHeight(node->left), getHeight(node->right)); 194 | 195 | int balance = getBalanceFactor(node); 196 | 197 | // Left-Left case 198 | if (balance > 1 && key < node->left->key) 199 | return rightRotate(node); 200 | 201 | // Right-Right case 202 | if (balance < -1 && key > node->right->key) 203 | return leftRotate(node); 204 | 205 | // Left-Right case 206 | if (balance > 1 && key > node->left->key) { 207 | node->left = leftRotate(node->left); 208 | return rightRotate(node); 209 | } 210 | 211 | // Right-Left case 212 | if (balance < -1 && key < node->right->key) { 213 | node->right = rightRotate(node->right); 214 | return leftRotate(node); 215 | } 216 | 217 | return node; 218 | } 219 | 220 | void inorderTraversal(Node* node) { 221 | if (node != nullptr) { 222 | inorderTraversal(node->left); 223 | std::cout << node->key << " "; 224 | inorderTraversal(node->right); 225 | } 226 | } 227 | -------------------------------------------------------------------------------- /Trees/Inorder-Traversal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class TreeNode { 5 | public: 6 | int val; 7 | TreeNode* left; 8 | TreeNode* right; 9 | TreeNode(int value) : val(value), left(nullptr), right(nullptr) {} 10 | }; 11 | 12 | void inorderTraversal(TreeNode* root) { 13 | if (!root) return; 14 | inorderTraversal(root->left); 15 | cout << root->val << " "; 16 | inorderTraversal(root->right); 17 | } 18 | 19 | int main() { 20 | TreeNode* root = new TreeNode(1); 21 | root->left = new TreeNode(2); 22 | root->right = new TreeNode(3); 23 | root->left->left = new TreeNode(4); 24 | root->left->right = new TreeNode(5); 25 | 26 | cout << "Inorder Traversal: "; 27 | inorderTraversal(root); 28 | cout << endl; 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Trees/LCA_of_BST.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class TreeNode { 4 | public: 5 | int val; 6 | TreeNode* left; 7 | TreeNode* right; 8 | 9 | TreeNode(int value) : val(value), left(nullptr), right(nullptr) {} 10 | }; 11 | 12 | TreeNode* findLCA(TreeNode* root, int node1, int node2) { 13 | if (root == nullptr) 14 | return nullptr; 15 | 16 | if (root->val > node1 && root->val > node2) 17 | return findLCA(root->left, node1, node2); 18 | else if (root->val < node1 && root->val < node2) 19 | return findLCA(root->right, node1, node2); 20 | else 21 | return root; 22 | } 23 | 24 | int main() { 25 | // Create a BST 26 | TreeNode* root = new TreeNode(20); 27 | root->left = new TreeNode(10); 28 | root->right = new TreeNode(30); 29 | root->left->left = new TreeNode(5); 30 | root->left->right = new TreeNode(15); 31 | root->right->left = new TreeNode(25); 32 | root->right->right = new TreeNode(35); 33 | 34 | int node1 = 5; 35 | int node2 = 15; 36 | 37 | TreeNode* lca = findLCA(root, node1, node2); 38 | 39 | if (lca != nullptr) 40 | std::cout << "LCA of " << node1 << " and " << node2 << " is " << lca->val << std::endl; 41 | else 42 | std::cout << "LCA not found for " << node1 << " and " << node2 << std::endl; 43 | 44 | // Deallocate memory (optional but recommended) 45 | // You can implement a separate function to delete the tree. 46 | delete root->left->left; 47 | delete root->left->right; 48 | delete root->right->left; 49 | delete root->right->right; 50 | delete root->left; 51 | delete root->right; 52 | delete root; 53 | 54 | return 0; 55 | } 56 | -------------------------------------------------------------------------------- /Trees/Max_path_sum_in_BT.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | struct TreeNode { 6 | int val; 7 | TreeNode* left; 8 | TreeNode* right; 9 | TreeNode(int x) : val(x), left(NULL), right(NULL) {} 10 | }; 11 | 12 | int maxPathSumUtil(TreeNode* root, int& res) { 13 | if (root == NULL) 14 | return 0; 15 | 16 | int left = max(0, maxPathSumUtil(root->left, res)); 17 | int right = max(0, maxPathSumUtil(root->right, res)); 18 | 19 | res = max(res, left + right + root->val); 20 | 21 | return max(left, right) + root->val; 22 | } 23 | 24 | int maxPathSum(TreeNode* root) { 25 | int res = INT_MIN; 26 | maxPathSumUtil(root, res); 27 | return res; 28 | } 29 | 30 | int main() { 31 | TreeNode* root = new TreeNode(1); 32 | root->left = new TreeNode(2); 33 | root->right = new TreeNode(3); 34 | 35 | cout << maxPathSum(root) << endl; 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Trees/Morris_traversal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct TreeNode { 4 | int val; 5 | TreeNode* left; 6 | TreeNode* right; 7 | TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} 8 | }; 9 | 10 | void morrisTraversal(TreeNode* root) { 11 | TreeNode* current = root; 12 | while (current) { 13 | if (!current->left) { 14 | std::cout << current->val << " "; 15 | current = current->right; 16 | } else { 17 | TreeNode* predecessor = current->left; 18 | while (predecessor->right && predecessor->right != current) { 19 | predecessor = predecessor->right; 20 | } 21 | 22 | if (!predecessor->right) { 23 | predecessor->right = current; 24 | current = current->left; 25 | } else { 26 | predecessor->right = nullptr; 27 | std::cout << current->val << " "; 28 | current = current->right; 29 | } 30 | } 31 | } 32 | } 33 | 34 | int main() { 35 | // Example usage: 36 | TreeNode* root = new TreeNode(1); 37 | root->left = new TreeNode(2); 38 | root->right = new TreeNode(3); 39 | root->left->left = new TreeNode(4); 40 | root->left->right = new TreeNode(5); 41 | 42 | std::cout << "Morris Traversal: "; 43 | morrisTraversal(root); 44 | 45 | return 0; 46 | } 47 | -------------------------------------------------------------------------------- /Trees/Postorder-Traversal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class TreeNode { 5 | public: 6 | int val; 7 | TreeNode* left; 8 | TreeNode* right; 9 | TreeNode(int value) : val(value), left(nullptr), right(nullptr) {} 10 | }; 11 | 12 | void postorderTraversal(TreeNode* root) { 13 | if (!root) return; 14 | postorderTraversal(root->left); 15 | postorderTraversal(root->right); 16 | cout << root->val << " "; 17 | } 18 | 19 | int main() { 20 | TreeNode* root = new TreeNode(1); 21 | root->left = new TreeNode(2); 22 | root->right = new TreeNode(3); 23 | root->left->left = new TreeNode(4); 24 | root->left->right = new TreeNode(5); 25 | 26 | cout << "Postorder Traversal: "; 27 | postorderTraversal(root); 28 | cout << endl; 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Trees/Preorder-Traversal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | class TreeNode { 5 | public: 6 | int val; 7 | TreeNode* left; 8 | TreeNode* right; 9 | TreeNode(int value) : val(value), left(nullptr), right(nullptr) {} 10 | }; 11 | 12 | void preorderTraversal(TreeNode* root) { 13 | if (!root) return; 14 | cout << root->val << " "; 15 | preorderTraversal(root->left); 16 | preorderTraversal(root->right); 17 | } 18 | 19 | int main() { 20 | TreeNode* root = new TreeNode(1); 21 | root->left = new TreeNode(2); 22 | root->right = new TreeNode(3); 23 | root->left->left = new TreeNode(4); 24 | root->left->right = new TreeNode(5); 25 | 26 | cout << "preorder Traversal: "; 27 | preorderTraversal(root); 28 | cout << endl; 29 | 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /Trees/Red_Black_Trees_Implementation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | enum Color { RED, BLACK }; 4 | 5 | class Node { 6 | public: 7 | int key; 8 | Color color; 9 | Node* left; 10 | Node* right; 11 | Node* parent; 12 | 13 | Node(int k, Color c) : key(k), color(c), left(nullptr), right(nullptr), parent(nullptr) {} 14 | }; 15 | 16 | class RedBlackTree { 17 | private: 18 | Node* root; 19 | Node* nil; // Sentinel node representing null 20 | 21 | void leftRotate(Node* x) { 22 | Node* y = x->right; 23 | x->right = y->left; 24 | 25 | if (y->left != nil) 26 | y->left->parent = x; 27 | 28 | y->parent = x->parent; 29 | 30 | if (x->parent == nil) 31 | root = y; 32 | else if (x == x->parent->left) 33 | x->parent->left = y; 34 | else 35 | x->parent->right = y; 36 | 37 | y->left = x; 38 | x->parent = y; 39 | } 40 | 41 | void rightRotate(Node* y) { 42 | Node* x = y->left; 43 | y->left = x->right; 44 | 45 | if (x->right != nil) 46 | x->right->parent = y; 47 | 48 | x->parent = y->parent; 49 | 50 | if (y->parent == nil) 51 | root = x; 52 | else if (y == y->parent->left) 53 | y->parent->left = x; 54 | else 55 | y->parent->right = x; 56 | 57 | x->right = y; 58 | y->parent = x; 59 | } 60 | 61 | void insertFixup(Node* z) { 62 | while (z->parent->color == RED) { 63 | if (z->parent == z->parent->parent->left) { 64 | Node* y = z->parent->parent->right; 65 | if (y->color == RED) { 66 | z->parent->color = BLACK; 67 | y->color = BLACK; 68 | z->parent->parent->color = RED; 69 | z = z->parent->parent; 70 | } else { 71 | if (z == z->parent->right) { 72 | z = z->parent; 73 | leftRotate(z); 74 | } 75 | z->parent->color = BLACK; 76 | z->parent->parent->color = RED; 77 | rightRotate(z->parent->parent); 78 | } 79 | } else { 80 | Node* y = z->parent->parent->left; 81 | if (y->color == RED) { 82 | z->parent->color = BLACK; 83 | y->color = BLACK; 84 | z->parent->parent->color = RED; 85 | z = z->parent->parent; 86 | #include 87 | 88 | enum Color { RED, BLACK }; 89 | 90 | class Node { 91 | public: 92 | int key; 93 | Color color; 94 | Node* left; 95 | Node* right; 96 | Node* parent; 97 | 98 | Node(int k, Color c) : key(k), color(c), left(nullptr), right(nullptr), parent(nullptr) {} 99 | }; 100 | 101 | class RedBlackTree { 102 | private: 103 | Node* root; 104 | Node* nil; // Sentinel node representing null 105 | 106 | void leftRotate(Node* x) { 107 | Node* y = x->right; 108 | x->right = y->left; 109 | 110 | if (y->left != nil) 111 | y->left->parent = x; 112 | 113 | y->parent = x->parent; 114 | 115 | if (x->parent == nil) 116 | root = y; 117 | else if (x == x->parent->left) 118 | x->parent->left = y; 119 | else 120 | x->parent->right = y; 121 | 122 | y->left = x; 123 | x->parent = y; 124 | } 125 | 126 | void rightRotate(Node* y) { 127 | Node* x = y->left; 128 | y->left = x->right; 129 | 130 | if (x->right != nil) 131 | x->right->parent = y; 132 | 133 | x->parent = y->parent; 134 | 135 | if (y->parent == nil) 136 | root = x; 137 | else if (y == y->parent->left) 138 | y->parent->left = x; 139 | else 140 | y->parent->right = x; 141 | 142 | x->right = y; 143 | y->parent = x; 144 | } 145 | 146 | void insertFixup(Node* z) { 147 | while (z->parent->color == RED) { 148 | if (z->parent == z->parent->parent->left) { 149 | Node* y = z->parent->parent->right; 150 | if (y->color == RED) { 151 | z->parent->color = BLACK; 152 | y->color = BLACK; 153 | z->parent->parent->color = RED; 154 | z = z->parent->parent; 155 | } else { 156 | if (z == z->parent->right) { 157 | z = z->parent; 158 | leftRotate(z); 159 | } 160 | z->parent->color = BLACK; 161 | z->parent->parent->color = RED; 162 | rightRotate(z->parent->parent); 163 | } 164 | } else { 165 | Node* y = z->parent->parent->left; 166 | if (y->color == RED) { 167 | z->parent->color = BLACK; 168 | y->color = BLACK; 169 | z->parent->parent->color = RED; 170 | z = z->parent->parent; 171 | } else { 172 | if (z == z->parent->left) { 173 | z = z->parent; 174 | rightRotate(z); 175 | } 176 | z->parent->color = BLACK; 177 | z->parent->parent->color = RED; 178 | leftRotate(z->parent->parent); 179 | } 180 | } 181 | } 182 | root->color = BLACK; 183 | } 184 | 185 | void insert(Node* z) { 186 | Node* y = nil; 187 | Node* x = root; 188 | 189 | while (x != nil) { 190 | y = x; 191 | if (z->key < x->key) 192 | x = x->left; 193 | else 194 | x = x->right; 195 | } 196 | 197 | z->parent = y; 198 | if (y == nil) 199 | root = z; 200 | else if (z->key < y->key) 201 | y->left = z; 202 | else 203 | y->right = z; 204 | 205 | z->left = nil; 206 | z->right = nil; 207 | z->color = RED; 208 | 209 | insertFixup(z); 210 | } 211 | 212 | void inorderTraversal(Node* x) { 213 | if (x != nil) { 214 | inorderTraversal(x->left); 215 | std::cout << x->key << "(" << (x->color == RED ? "RED" : "BLACK") << ") "; 216 | inorderTraversal(x->right); 217 | } 218 | } 219 | 220 | public: 221 | RedBlackTree() { 222 | nil = new Node(-1, BLACK); 223 | root = nil; 224 | } 225 | 226 | void insert(int key) { 227 | Node* z = new Node(key, BLACK); 228 | insert(z); 229 | } 230 | 231 | void printInorder() { 232 | inorderTraversal(root); 233 | std::cout << std::endl; 234 | } 235 | }; 236 | 237 | int main() { 238 | RedBlackTree rbTree; 239 | 240 | rbTree.insert(10); 241 | rbTree.insert(20); 242 | rbTree.insert(30); 243 | 244 | std::cout << "Inorder traversal of the Red-Black Tree: "; 245 | rbTree.printInorder(); 246 | 247 | return 0; 248 | } 249 | -------------------------------------------------------------------------------- /Trees/Set-Using-Binary-Search-Tree.cpp: -------------------------------------------------------------------------------- 1 | // Implementation Of Set Using Binary Search Tree 2 | 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | 8 | // TreeNode Implementation 9 | 10 | class Node{ 11 | public: 12 | int val; 13 | Node* left, *right; 14 | Node(int v){ 15 | val = v; 16 | left = NULL; 17 | right = NULL; 18 | } 19 | }; 20 | 21 | 22 | // TreeSet implementation 23 | 24 | class TreeSet{ 25 | public: 26 | Node* root; // root of the tree 27 | 28 | TreeSet(Node* r){ 29 | root = r; 30 | } 31 | 32 | // value insertion O(log n) 33 | 34 | void insert(int value){ 35 | Node* neww = new Node(value); 36 | Node* x = root; 37 | while(x->val != value){ 38 | if(value > x->val){ 39 | if(!x->right)break; 40 | x = x->right; 41 | } 42 | else{ 43 | if(!x->left)break; 44 | x = x->left; 45 | } 46 | } 47 | if(x->val == value)return; 48 | if(x->val > value)x->left = neww; 49 | else x->right = neww; 50 | } 51 | 52 | // search in O(log n) 53 | 54 | bool search(int value){ 55 | Node* cur = root; 56 | while(cur){ 57 | if(cur->val == value)return true; 58 | if(cur->val > value)cur = cur->left; 59 | else cur = cur->right; 60 | } 61 | 62 | return false; 63 | } 64 | 65 | 66 | // dfs function 67 | 68 | void dfs(Node* root){ 69 | if(!root)return; 70 | dfs(root->left); 71 | cout << root->val << " "; 72 | dfs(root->right); 73 | } 74 | 75 | // prints set in order O(n) 76 | 77 | void print(){ 78 | Node* cur = root; 79 | dfs(cur); 80 | cout << "\n"; 81 | } 82 | 83 | }; 84 | 85 | // union method O(n*log m) 86 | 87 | // makes a copy of a tree 88 | void dfs(Node* root, TreeSet* st){ 89 | if(!root)return; 90 | st->insert(root->val); 91 | dfs(root->left, st); 92 | dfs(root->right, st); 93 | } 94 | 95 | TreeSet* deepcopy(TreeSet* st){ 96 | TreeSet* neww = new TreeSet(new Node(st->root->val)); 97 | dfs(st->root, neww); 98 | return neww; 99 | } 100 | 101 | // union function 102 | TreeSet* uni(TreeSet* st1, TreeSet* st2){ 103 | TreeSet* st3 = deepcopy(st1); 104 | dfs(st2->root, st3); 105 | return st3; 106 | } 107 | 108 | 109 | 110 | // intersection method O(n*log m) 111 | 112 | // finds common nodes between two trees 113 | void findCommon(Node* root, vector &common, TreeSet* st2){ 114 | if(!root)return; 115 | if(st2->search(root->val))common.push_back(root->val); 116 | findCommon(root->left, common, st2); 117 | findCommon(root->right, common, st2); 118 | } 119 | 120 | // intersection function 121 | TreeSet* intersection(TreeSet* st1, TreeSet* st2){ 122 | vector common; 123 | findCommon(st1->root, common, st2); 124 | if(common.empty())return nullptr; 125 | TreeSet* neww = new TreeSet(new Node(common[0])); 126 | for(int i=1; iinsert(common[i]); 127 | return neww; 128 | } 129 | 130 | 131 | 132 | void solve() 133 | { 134 | // declaring the sets 135 | Node* head1 = new Node(100); 136 | Node* head2 = new Node(329); 137 | TreeSet* set1 = new TreeSet(head1); 138 | TreeSet* set2 = new TreeSet(head2); 139 | 140 | // first set insertion 141 | set1->insert(80); 142 | set1->insert(120); 143 | set1->insert(30); 144 | set1->insert(90); 145 | set1->insert(200); 146 | set1->insert(200); 147 | 148 | // second set insertion 149 | set2->insert(186); 150 | set2->insert(120); 151 | set2->insert(500); 152 | set2->insert(432); 153 | set2->insert(20); 154 | set2->insert(30); 155 | 156 | // union 157 | TreeSet* union1 = uni(set1, set2); 158 | union1->print(); // 30 & 120 common in 2 sets but uni function unites them and removes duplicates 159 | 160 | // intersection 161 | TreeSet* intersection1 = intersection(set1, set2); 162 | intersection1->print(); // 30 & 120 is common and intersection function prints exactly the same 163 | } 164 | 165 | /* Main() function */ 166 | 167 | int main() 168 | { 169 | solve(); 170 | return 0; 171 | } -------------------------------------------------------------------------------- /Trees/Zigzag_traversal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | struct TreeNode { 8 | int val; 9 | TreeNode *left; 10 | TreeNode *right; 11 | TreeNode(int x) : val(x), left(NULL), right(NULL) {} 12 | }; 13 | 14 | vector> zigzagLevelOrder(TreeNode* root) { 15 | vector> result; 16 | if (!root) return result; 17 | 18 | stack currentLevel; 19 | stack nextLevel; 20 | bool leftToRight = true; 21 | 22 | currentLevel.push(root); 23 | vector levelValues; 24 | 25 | while (!currentLevel.empty()) { 26 | TreeNode* node = currentLevel.top(); 27 | currentLevel.pop(); 28 | 29 | if (node) { 30 | levelValues.push_back(node->val); 31 | if (leftToRight) { 32 | if (node->left) nextLevel.push(node->left); 33 | if (node->right) nextLevel.push(node->right); 34 | } else { 35 | if (node->right) nextLevel.push(node->right); 36 | if (node->left) nextLevel.push(node->left); 37 | } 38 | } 39 | 40 | if (currentLevel.empty()) { 41 | result.push_back(levelValues); 42 | levelValues.clear(); 43 | leftToRight = !leftToRight; 44 | swap(currentLevel, nextLevel); 45 | } 46 | } 47 | 48 | return result; 49 | } 50 | 51 | TreeNode* newNode(int data) { 52 | TreeNode* node = new TreeNode(data); 53 | return node; 54 | } 55 | 56 | int main() { 57 | TreeNode* root = newNode(3); 58 | root->left = newNode(9); 59 | root->right = newNode(20); 60 | root->right->left = newNode(15); 61 | root->right->right = newNode(7); 62 | 63 | vector> zigzagTraversal = zigzagLevelOrder(root); 64 | 65 | cout << "Zigzag traversal:" << endl; 66 | for (const auto& level : zigzagTraversal) { 67 | for (const auto& val : level) { 68 | cout << val << " "; 69 | } 70 | cout << endl; 71 | } 72 | 73 | return 0; 74 | } 75 | Enter 76 | -------------------------------------------------------------------------------- /Trees/common_node_in_bst.cpp: -------------------------------------------------------------------------------- 1 | //{ Driver Code Starts 2 | #include 3 | using namespace std; 4 | // Tree Node 5 | struct Node { 6 | int data; 7 | Node *left; 8 | Node *right; 9 | Node(int val) { 10 | data = val; 11 | left = right = NULL; 12 | } 13 | }; 14 | // Function to Build Tree 15 | Node* buildTree(string str){ 16 | // Corner Case 17 | if(str.length() == 0 || str[0] == 'N') 18 | return NULL; 19 | // Creating vector of strings from input 20 | // string after spliting by space 21 | vector ip; 22 | istringstream iss(str); 23 | for(string str; iss >> str; ) 24 | ip.push_back(str); 25 | // Create the root of the tree 26 | Node* root = new Node(stoi(ip[0])); 27 | // Push the root to the queue 28 | queue queue; 29 | queue.push(root); 30 | // Starting from the second element 31 | int i = 1; 32 | while(!queue.empty() && i < ip.size()) { 33 | // Get and remove the front of the queue 34 | Node* currNode = queue.front(); 35 | queue.pop(); 36 | // Get the current node's value from the string 37 | string currVal = ip[i]; 38 | // If the left child is not null 39 | if(currVal != "N") { 40 | // Create the left child for the current node 41 | currNode->left = new Node(stoi(currVal)); 42 | // Push it to the queue 43 | queue.push(currNode->left); 44 | } 45 | // For the right child 46 | i++; 47 | if(i >= ip.size()) 48 | break; 49 | currVal = ip[i]; 50 | // If the right child is not null 51 | if(currVal != "N") { 52 | // Create the right child for the current node 53 | currNode->right = new Node(stoi(currVal)); 54 | // Push it to the queue 55 | queue.push(currNode->right); 56 | } 57 | i++; 58 | } 59 | return root; 60 | } 61 | class Solution 62 | { 63 | public: 64 | //Function to find the nodes that are common in both BST. 65 | void traversal(Node*root,unordered_set&st,vector&ans){ 66 | if(root){ 67 | if(st.find(root->data)==st.end()) 68 | st.insert(root->data); 69 | else 70 | ans.push_back(root->data); 71 | traversal(root->left,st,ans); 72 | traversal(root->right,st,ans); 73 | } 74 | } 75 | vector findCommon(Node *root1, Node *root2) 76 | { 77 | //Your code here 78 | unordered_setst; 79 | vectorans; 80 | traversal(root1,st,ans); 81 | traversal(root2,st,ans); 82 | sort(ans.begin(),ans.end()); 83 | return ans; 84 | } 85 | }; 86 | int main() 87 | { 88 | string s1,s2; 89 | Node* root1 = buildTree(s1); 90 | Node* root2 = buildTree(s2); 91 | Solution ob;` 92 | vector res = ob.findCommon(root1, root2); 93 | for (int i : res) 94 | cout << i << " "; 95 | cout<< endl; 96 | } 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /Trees/is_duplicate_subtree_in_tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | struct Node 4 | { 5 | char data; 6 | struct Node *left; 7 | struct Node *right; 8 | 9 | Node(char x) { 10 | data = x; 11 | left = NULL; 12 | right = NULL; 13 | } 14 | }; 15 | //code for building tree 16 | struct Node* buildTree(string str) 17 | { 18 | // Corner Case 19 | if (str.length() == 0 || str[0] == 'N') 20 | return NULL; 21 | // Creating vector of strings from input 22 | // string after spliting by space 23 | vector ip; 24 | istringstream iss(str); 25 | for (string str; iss >> str; ) 26 | ip.push_back(str); 27 | // Create the root of the tree 28 | Node *root = new Node(stoi(ip[0])); 29 | // Push the root to the queue 30 | queue queue; 31 | queue.push(root); 32 | // Starting from the second element 33 | int i = 1; 34 | while (!queue.empty() && i < ip.size()) { 35 | // Get and remove the front of the queue 36 | Node* currNode = queue.front(); 37 | queue.pop(); 38 | // Get the current node's value from the string 39 | string currVal = ip[i]; 40 | // If the left child is not null 41 | if (currVal != "N") { 42 | // Create the left child for the current Node 43 | currNode->left = new Node(stoi(currVal)); 44 | // Push it to the queue 45 | queue.push(currNode->left); 46 | } 47 | // For the right child 48 | i++; 49 | if (i >= ip.size()) 50 | break; 51 | currVal = ip[i]; 52 | // If the right child is not null 53 | if (currVal != "N") { 54 | // Create the right child for the current node 55 | currNode->right = new Node(stoi(currVal)); 56 | // Push it to the queue 57 | queue.push(currNode->right); 58 | } 59 | i++; 60 | } 61 | return root; 62 | } 63 | class Solution { 64 | public: 65 | /*This function returns true if the tree contains 66 | a duplicate subtree of size 2 or more else returns false*/ 67 | int dupSub(Node *root) { 68 | unordered_mapmp; 69 | queueq; 70 | q.push(root); 71 | int cnt=0; 72 | while(!q.empty()){ 73 | Node*temp=q.front();q.pop(); 74 | string t; 75 | cnt=0; 76 | bool fg=true; 77 | t.push_back(temp->data+'0'); 78 | if(temp->left){ 79 | q.push(temp->left); 80 | t.push_back(temp->left->data+'0'); 81 | cnt++; 82 | if(temp->left->left!=NULL||temp->left->right!=NULL) 83 | fg=false; 84 | } 85 | else 86 | t.push_back('@'); 87 | if(temp->right){ 88 | q.push(temp->right); 89 | t.push_back(temp->right->data+'0'); 90 | cnt++; 91 | if(temp->right->left!=NULL||temp->right->right!=NULL) 92 | fg=false; 93 | } 94 | else 95 | t.push_back('@'); 96 | if(t.size()>1&&cnt>0&&fg&&mp.find(t)!=mp.end())return true; 97 | else if(t.size()>1&&cnt>0&&fg) mp[t]++; 98 | //string tt; 99 | t=""; 100 | } 101 | return false; 102 | } 103 | }; 104 | int main() 105 | { 106 | int t; 107 | cin >> t; 108 | //cout << t << "\n"; 109 | while (t--) 110 | { 111 | string treeString; 112 | getline(cin >> ws, treeString); 113 | struct Node* root = buildTree(treeString); 114 | Solution ob; 115 | cout << ob.dupSub(root) << "\n"; 116 | } 117 | return 0; 118 | } 119 | --------------------------------------------------------------------------------