├── BACKTRACKING ├── 15_find_if_there_is_path_of_more_than_k_length_from_source.cpp ├── 00_intro.cpp ├── 10_tug_of_war.cpp ├── 03_word_break_problem_using_backtracking.cpp ├── 04_remove_invalid_paranthesis.cpp ├── 05_sudoku_solver.cpp ├── 08_subset_sum_problem.cpp ├── 17_print_all_possible_path_from_top_left_to_bottom_right_in_MN_matrix.cpp ├── 07_print_all_palindromic_partitions_of_string.cpp ├── 14_print_all_permutations_of_string.cpp ├── 19_kth_permutation_sequence_of_first_N_natural_no.cpp └── 09_knights_tour_problem.cpp ├── love_babbar_FINAL450.xlsx ├── 450 DSA Cracker (I did it).jpg ├── GREEDY ├── 24_chocolate_distribution_problem.cpp ├── 17_maximize_sum_of_arr_i_into_i.cpp ├── 34_rearrange_characters_in_string_such_that_no_2_adjacent_are_same.cpp ├── 20_min_sum_of_absolute_difference_in_pair_of_2_arrays.cpp ├── 13_check_if_its_possible_to_survive_on_island.cpp ├── 19_maximum_sum_of_consecutive_difference_in_circular_array.cpp ├── 09_buy_maximum_stock_if_can_be_bought_on_ith_day.cpp ├── 01_activity_selection_problem.cpp ├── 30_ARRANGE_arranging_amplifiers.cpp ├── 32_minimum_cost_of_ropes.cpp ├── 29_CHOCOLA_choclate.cpp ├── 23_smallest_subset_with_sum_greater_than_all_other_element.cpp ├── 02_job_sequencing_problem.cpp ├── 10_max_min_amount_to_buy_all_candy.cpp ├── 28_picking_up_chicks.cpp ├── 25_DEFKIN_defence_of_kingdom.cpp ├── 27_GERGOVIA_wine_trading_in_gergovia.cpp ├── 08_minimum_platform_problem.cpp ├── 07_maximum_trains_for_which_stoppage_can_be_provided.cpp ├── 33_find_smallest_no_given_total_no_of_digits_and_sum_of_digits.cpp ├── 21_shortest_job_first_SJF.cpp ├── 15_maximum_product_subset_of_an_array.cpp ├── 35_find_maximum_sum_possible_equal_sum_of_three_stacks.cpp ├── 06_find_minimum_no_of_coins.cpp ├── 05_fractional_knapsack_problem.cpp ├── 31_K_centers_problem.cpp ├── 14_find_maximum_meetings_in_one_room.cpp ├── 12_min_cost_to_cut_board_into_square.cpp ├── 22_least_recently_used_LRU_page_replacement.cpp ├── 26_die_hard.cpp ├── 18_maximum_sum_of_absolute_difference_of_an_array.cpp └── 04_water_connection_problem.cpp ├── Greedy ├── 24_chocolate_distribution_problem.cpp ├── 17_maximize_sum_of_arr_i_into_i.cpp ├── 34_rearrange_characters_in_string_such_that_no_2_adjacent_are_same.cpp ├── 20_min_sum_of_absolute_difference_in_pair_of_2_arrays.cpp ├── 13_check_if_its_possible_to_survive_on_island.cpp ├── 19_maximum_sum_of_consecutive_difference_in_circular_array.cpp ├── 09_buy_maximum_stock_if_can_be_bought_on_ith_day.cpp ├── 01_activity_selection_problem.cpp ├── 30_ARRANGE_arranging_amplifiers.cpp ├── 32_minimum_cost_of_ropes.cpp ├── 29_CHOCOLA_choclate.cpp ├── 23_smallest_subset_with_sum_greater_than_all_other_element.cpp ├── 02_job_sequencing_problem.cpp ├── 10_max_min_amount_to_buy_all_candy.cpp ├── 28_picking_up_chicks.cpp ├── 25_DEFKIN_defence_of_kingdom.cpp ├── 27_GERGOVIA_wine_trading_in_gergovia.cpp ├── 08_minimum_platform_problem.cpp ├── 07_maximum_trains_for_which_stoppage_can_be_provided.cpp ├── 33_find_smallest_no_given_total_no_of_digits_and_sum_of_digits.cpp ├── 21_shortest_job_first_SJF.cpp ├── 15_maximum_product_subset_of_an_array.cpp ├── 35_find_maximum_sum_possible_equal_sum_of_three_stacks.cpp ├── 06_find_minimum_no_of_coins.cpp ├── 05_fractional_knapsack_problem.cpp ├── 31_K_centers_problem.cpp ├── 14_find_maximum_meetings_in_one_room.cpp ├── 12_min_cost_to_cut_board_into_square.cpp ├── 22_least_recently_used_LRU_page_replacement.cpp ├── 26_die_hard.cpp └── 18_maximum_sum_of_absolute_difference_of_an_array.cpp ├── TRIE ├── 04_given_sequence_of_words_print_all_anagrams_together.cpp ├── extra_05_suffix_trie.cpp ├── 06_print_unique_rows_in_given_boolean_matrix.cpp ├── extra_07_biggest_xor.cpp ├── extra_06_cute_cat.cpp ├── extra_04_longest_duplicate_sub_string.cpp └── 05_implement_phone_directory.cpp ├── DP ├── 06_Longest_Palindromic_Subsequence.cpp ├── 07_Minimum_number_of_deletion_in_a_string_to_make_it_a_palindrome.cpp ├── 36_smallest_sum_contiguous_subarray.cpp ├── 21_max_sum_increasing_subsequence.cpp ├── 30_max_diff_0_and_1.cpp ├── 03_coin_change.cpp ├── 10_permutation_coefficient_problem.cpp ├── 33_unbound_knapsack.cpp ├── 16_maximize_cut_segment.cpp ├── 04_LC_subsequences.cpp ├── 05_LC_substring.cpp ├── 60_matrix_chain_multiplication.cpp ├── 29_max_path_sum_in_matrix.cpp ├── 23_longest_subsequence_adj_diff_1.cpp ├── 25_max_sum_no_three_are_consequetive.cpp ├── 51_max_sum_of_pair_with_specific_diff.cpp ├── 24_max_sum_no_two_ele_are_adjacent.cpp ├── 32_partition_problem.cpp ├── 28_max_length_chain_of_pairs.cpp ├── 08_longest_repeated_subsequence.cpp ├── 20_LCS_of_3_string.cpp ├── 55_word_break_problem.cpp ├── 19_LCS_space_optimized.cpp ├── 22_count_all_subsequence_product_less_than_k.cpp ├── 14_friend_pairing_problem.cpp ├── 44_optimal_strategy_for_game.cpp ├── 52_Maximum_size_square_sub-matrix_with_all_1.cpp ├── 02_equal_subset-sum.cpp ├── 46_all_count_palindromic_subsequence.cpp ├── 17_painting_the_fence.cpp ├── 54_count_balance_binary_tree.cpp ├── 50_coin_game_winner_three_choice.cpp ├── 49_count_derangements.cpp ├── 35_kadanes_algo_OR_largest_sum_contigous_array.cpp ├── 34_count_no_of_ways_to_reach_given_score.cpp ├── 26_min_cost_to_fill_in_given_weights.cpp ├── 38_interleaved_string.cpp ├── 45_palindrom_partition_problem.cpp ├── 48_weighted_job_scheduling.cpp ├── 37_longest_alternating_subsequence.cpp ├── 11_egg_dropping_problem.cpp └── 15_gold_mine.cpp └── README.md /BACKTRACKING/15_find_if_there_is_path_of_more_than_k_length_from_source.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ref: graph/36_find_if_there... 3 | */ 4 | -------------------------------------------------------------------------------- /love_babbar_FINAL450.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shibam120302/Love-Babbar-DSA-Sheet-SOL/HEAD/love_babbar_FINAL450.xlsx -------------------------------------------------------------------------------- /450 DSA Cracker (I did it).jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shibam120302/Love-Babbar-DSA-Sheet-SOL/HEAD/450 DSA Cracker (I did it).jpg -------------------------------------------------------------------------------- /GREEDY/24_chocolate_distribution_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/chocolate-distribution-problem3825/1 3 | 4 | refer: array/30_chocolate_distribution.... 5 | */ 6 | 7 | -------------------------------------------------------------------------------- /Greedy/24_chocolate_distribution_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/chocolate-distribution-problem3825/1 3 | 4 | refer: array/30_chocolate_distribution.... 5 | */ 6 | 7 | -------------------------------------------------------------------------------- /TRIE/04_given_sequence_of_words_print_all_anagrams_together.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/print-anagrams-together/1 3 | 4 | ref: string/36_given_sequence_.... 5 | */ 6 | -------------------------------------------------------------------------------- /GREEDY/17_maximize_sum_of_arr_i_into_i.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/maximize-arrii-of-an-array0026/1# 3 | 4 | sol: https://www.geeksforgeeks.org/maximize-sum-arrii/ 5 | */ 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | /* 10 | TC: O(N logN) 11 | */ 12 | 13 | const long long int mod = (int)1e9 + 7; 14 | int Maximize(int a[], int n) 15 | { 16 | long long int pro = 0; 17 | sort(a, a + n); 18 | for (int i = 1; i < n; i++) { 19 | pro += (i * (a[i] % mod)) % mod; 20 | pro = pro % mod; 21 | } 22 | return pro; 23 | } -------------------------------------------------------------------------------- /Greedy/17_maximize_sum_of_arr_i_into_i.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/maximize-arrii-of-an-array0026/1# 3 | 4 | sol: https://www.geeksforgeeks.org/maximize-sum-arrii/ 5 | */ 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | /* 10 | TC: O(N logN) 11 | */ 12 | 13 | const long long int mod = (int)1e9 + 7; 14 | int Maximize(int a[], int n) 15 | { 16 | long long int pro = 0; 17 | sort(a, a + n); 18 | for (int i = 1; i < n; i++) { 19 | pro += (i * (a[i] % mod)) % mod; 20 | pro = pro % mod; 21 | } 22 | return pro; 23 | } -------------------------------------------------------------------------------- /BACKTRACKING/00_intro.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | what is backtracking ? 3 | video: https://youtu.be/SJ_pXT-L5IE 4 | 5 | how it is implemented (logically) 6 | video: https://youtu.be/DKCbsiDBN6c 7 | 8 | 9 | Backtracking Algorithm: 10 | Backtracking is an algorithmic-technique for solving problems recursively by trying 11 | to build a solution incrementally. Solving one piece at a time, and removing those solutions 12 | that fail to satisfy the constraints of the problem at any point of time (by time, here, 13 | is referred to the time elapsed till reaching any level of the search tree) is the process of backtracking. 14 | 15 | */ 16 | -------------------------------------------------------------------------------- /DP/06_Longest_Palindromic_Subsequence.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | link: https://www.geeksforgeeks.org/longest-palindromic-subsequence-dp-12/ 4 | 5 | problem: given a string find longest palindromic subsequence 6 | output: length of longest palindromic subsequence 7 | 8 | refer DP_tut\3_LCS\6_Longest_Palindromic... 9 | 10 | crux of the problem: if we want to find the subsequence we use LCS 11 | then if want to find the palindromic then use the same string and reverse it. 12 | 13 | */ 14 | 15 | // ----------------------------------------------------------------------------------------------------------------------- // 16 | 17 | int main() { 18 | // string s2 = reverse of s1. 19 | return LCS(s1, s2, n, n); 20 | } -------------------------------------------------------------------------------- /DP/07_Minimum_number_of_deletion_in_a_string_to_make_it_a_palindrome.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/minimum-number-deletions-make-string-palindrome/ 3 | 4 | problem: given string find min. no. of deletion to make it palindrom. 5 | output: min. no. of operation 6 | 7 | crux: find subsequence with palindromic of string itself, and then subtract with the length 8 | refer: longest palindromic subsequnce. 9 | 10 | variation of LCS 11 | */ 12 | 13 | // ----------------------------------------------------------------------------------------------------------------------- // 14 | 15 | int main() { 16 | // string s2 = reverse of s1. 17 | return s1.length() - LCS(s1, s2, n, n); 18 | } 19 | 20 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /DP/36_smallest_sum_contiguous_subarray.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/smallest-sum-contiguous-subarray/ 3 | 4 | variation of kadanes algo 5 | 6 | refer: problem no. 35... 7 | */ 8 | 9 | // ----------------------------------------------------------------------------------------------------------------------- // 10 | 11 | int maxSubarraySum(int arr[], int n) { 12 | int dp[n]; 13 | 14 | dp[0] = max(0, arr[0]); 15 | int omin = dp[0]; 16 | for (int i = 1;i < n;i++) { 17 | // choosing either to keep the subarray continue or break and initialize with current ele. 18 | dp[i] = min(dp[i - 1] + arr[i], arr[i]); 19 | // also keeping track of highest sum achieved during the journey. 20 | omin = min(dp[i], omin); 21 | } 22 | return omin; 23 | } 24 | 25 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /DP/21_max_sum_increasing_subsequence.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/maximum-sum-increasing-subsequence-dp-14/ 3 | 4 | variation of LIS but here we have to return value's sum and not count... 5 | */ 6 | 7 | // ----------------------------------------------------------------------------------------------------------------------- // 8 | 9 | int maxSumIS(int arr[], int n) 10 | { 11 | int dp[n]; 12 | dp[0] = arr[0]; 13 | int omax = arr[0]; 14 | for (int i = 1;i < n;i++) { 15 | dp[i] = arr[i]; 16 | for (int j = 0;j < i;j++) { 17 | if (arr[i] > arr[j]) { 18 | dp[i] = max(dp[i], arr[i] + dp[j]); // this time we adding value of current value + prev highest value sum. 19 | } 20 | } 21 | omax = max(omax, dp[i]); 22 | } 23 | return omax; 24 | } 25 | 26 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /DP/30_max_diff_0_and_1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/maximum-difference-of-zeros-and-ones-in-binary-string4111/1 3 | */ 4 | 5 | // ----------------------------------------------------------------------------------------------------------------------- // 6 | 7 | int maxSubstring(string s) 8 | { 9 | int len = s.size(); 10 | int dp[len]; 11 | dp[0] = (s[0] == '1') ? -1 : 1; 12 | int omax = dp[0]; 13 | for (int i = 1;i < len;i++) { 14 | // if char is 1 then give it -1 or prev_count - 1. 15 | if (s[i] == '1') { 16 | dp[i] = max(-1, dp[i - 1] - 1); 17 | } 18 | // if char is 0 then 1 or prev_count + 1. 19 | else { 20 | dp[i] = max(1, dp[i - 1] + 1); 21 | } 22 | // main_part find overall max parallely. 23 | omax = max(omax, dp[i]); 24 | } 25 | return omax; 26 | } 27 | 28 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /DP/03_coin_change.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/coin-change2448/1 3 | 4 | variation of unbounded_knapsack for more refer to DP_tut/unbounded_knapsack/3_coin.... 5 | */ 6 | 7 | // ----------------------------------------------------------------------------------------------------------------------- // 8 | 9 | long long int count(int coins[], int n, int sum) 10 | { 11 | vector> memo(n + 1, vector(sum + 1)); 12 | for (int j = 0;j < sum + 1;j++) memo[0][j] = 0; 13 | for (int i = 1;i < n + 1;i++) memo[i][0] = 1; 14 | 15 | for (int i = 1;i < n + 1;i++) { 16 | for (int j = 1;j < sum + 1;j++) { 17 | if (coins[i - 1] <= j) { 18 | memo[i][j] = memo[i][j - coins[i - 1]] + memo[i - 1][j]; 19 | } 20 | else memo[i][j] = memo[i - 1][j]; 21 | } 22 | } 23 | return memo[n][sum]; 24 | } 25 | 26 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /DP/10_permutation_coefficient_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/permutation-coefficient/ 3 | 4 | logic is same as 9_binomial_cofficient but here it is permutation 5 | */ 6 | 7 | // ----------------------------------------------------------------------------------------------------------------------- // 8 | 9 | // recursion 10 | // let's assume if n is the no. of balls and r is to position to fill 11 | int recur(int n, int r) { 12 | // base condition 13 | if (n < r) return 0; 14 | if (n == 0 || r == 0) return 1; 15 | 16 | return recur(n - 1, r) + (r * recur(n - 1, r - 1)); 17 | /* recur(n-1, r-1): it says select fixed ball hence total-1 and ball_left_to_select - 1 and now also there are r pos to permute that fixed ball. 18 | recur(n-1, r): it means reject that fixed ball hence total-1 and ball_left_to_select remains same. 19 | */ 20 | } 21 | 22 | // do memoization and tabulation by self. 23 | 24 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /DP/33_unbound_knapsack.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/knapsack-with-duplicate-items4201/1 3 | 4 | simple unbounded_knapsack 5 | refer: DP_tut/2_unbou../1_imple.. 6 | */ 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | 10 | int knapSack(int n, int w, int val[], int wt[]) 11 | { 12 | int dp[n + 1][w + 1]; 13 | for (int i = 0;i < n + 1;i++) dp[i][0] = 0; 14 | for (int j = 0;j < w + 1;j++) dp[0][j] = 0; 15 | 16 | for (int i = 1;i < n + 1;i++) { 17 | for (int j = 1;j < w + 1;j++) { 18 | // if current item's weight is less than the current weight limit 19 | if (wt[i - 1] <= j) { 20 | dp[i][j] = max(val[i - 1] + dp[i][j - wt[i - 1]], dp[i - 1][j]); 21 | } 22 | else dp[i][j] = dp[i - 1][j]; 23 | } 24 | } 25 | return dp[n][w]; 26 | } 27 | 28 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /GREEDY/34_rearrange_characters_in_string_such_that_no_2_adjacent_are_same.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/contest/coding-try-outs-amazon/problems 3 | 4 | sol (refer codes here): https://www.geeksforgeeks.org/rearrange-characters-string-no-two-adjacent/ 5 | 6 | video: https://youtu.be/69u_bfwoHm0 7 | 8 | */ 9 | 10 | 11 | // ----------------------------------------------------------------------------------------------------------------------- // 12 | /* 13 | using const. size array 14 | TC: O(N) 15 | */ 16 | #include 17 | using namespace std; 18 | 19 | int main() { 20 | int t; 21 | cin >> t; 22 | 23 | while (t--) { 24 | string s; 25 | cin >> s; 26 | 27 | int n = s.size(); 28 | 29 | int cnt[26] = { 0 }; 30 | 31 | // get count of every char 32 | for (int i = 0; i < n; i++) { 33 | cnt[s[i] - 'a']++; 34 | } 35 | 36 | int mx = 0; 37 | for (int i = 0; i < 26; i++) { 38 | mx = max(mx, cnt[i]); 39 | } 40 | 41 | if (mx <= (n + 1) / 2) { 42 | cout << 1 << endl; 43 | } 44 | else { 45 | cout << 0 << endl; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Greedy/34_rearrange_characters_in_string_such_that_no_2_adjacent_are_same.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/contest/coding-try-outs-amazon/problems 3 | 4 | sol (refer codes here): https://www.geeksforgeeks.org/rearrange-characters-string-no-two-adjacent/ 5 | 6 | video: https://youtu.be/69u_bfwoHm0 7 | 8 | */ 9 | 10 | 11 | // ----------------------------------------------------------------------------------------------------------------------- // 12 | /* 13 | using const. size array 14 | TC: O(N) 15 | */ 16 | #include 17 | using namespace std; 18 | 19 | int main() { 20 | int t; 21 | cin >> t; 22 | 23 | while (t--) { 24 | string s; 25 | cin >> s; 26 | 27 | int n = s.size(); 28 | 29 | int cnt[26] = { 0 }; 30 | 31 | // get count of every char 32 | for (int i = 0; i < n; i++) { 33 | cnt[s[i] - 'a']++; 34 | } 35 | 36 | int mx = 0; 37 | for (int i = 0; i < 26; i++) { 38 | mx = max(mx, cnt[i]); 39 | } 40 | 41 | if (mx <= (n + 1) / 2) { 42 | cout << 1 << endl; 43 | } 44 | else { 45 | cout << 0 << endl; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /DP/16_maximize_cut_segment.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/cutted-segments1642/1 3 | 4 | variation: unbounded DP 5 | */ 6 | 7 | // ----------------------------------------------------------------------------------------------------------------------- // 8 | 9 | // tabulation 10 | vector dp; 11 | int recur(int n, int x, int y, int z) 12 | { 13 | if (n <= 0) return 0; 14 | if (dp[n] != -1) return dp[n]; 15 | int a = INT_MIN - 1, b = INT_MIN - 1, c = INT_MIN - 1; 16 | if (n >= x) a = recur(n - x, x, y, z); 17 | if (n >= y) b = recur(n - y, x, y, z); 18 | if (n >= z) c = recur(n - z, x, y, z); 19 | 20 | // note: if no length can cut the segment than return INT_MIN. 21 | return dp[n] = 1 + max({ a, b, c }); 22 | } 23 | int maximizeTheCuts(int n, int x, int y, int z) { 24 | // memset(dp, -1, sizeof(dp)); 25 | dp = vector(n + 1, -1); 26 | int a = recur(n, x, y, z); 27 | return (a < 0) ? 0 : a; 28 | } 29 | 30 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /DP/04_LC_subsequences.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/longest-common-subsequence-1587115620/1 3 | 4 | refer DP_tut/LCS/implementation 5 | */ 6 | 7 | // ----------------------------------------------------------------------------------------------------------------------- // 8 | 9 | // function to find longest common subsequence 10 | int static memo[1001][1001]; 11 | int lcs(int n, int m, string s1, string s2) { 12 | 13 | // your code here 14 | for (int i = 0;i < n + 1;i++) { 15 | memo[i][0] = 0; 16 | } 17 | for (int j = 0;j < m + 1;j++) { 18 | memo[0][j] = 0; 19 | } 20 | for (int i = 1;i < n + 1;i++) { 21 | for (int j = 1;j < m + 1;j++) { 22 | if (s1[i - 1] == s2[j - 1]) { 23 | memo[i][j] = 1 + memo[i - 1][j - 1]; 24 | } 25 | else { 26 | memo[i][j] = max(memo[i - 1][j], memo[i][j - 1]); 27 | } 28 | } 29 | } 30 | return memo[n][m]; 31 | } 32 | 33 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /DP/05_LC_substring.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/longest-common-substring1452/1 3 | 4 | variation of DP_tut/LCS/2_LC_substring... 5 | */ 6 | 7 | // ----------------------------------------------------------------------------------------------------------------------- // 8 | 9 | int memo[1001][1001]; 10 | 11 | int longestCommonSubstr(string s1, string s2, int n, int m) 12 | { 13 | // memset(memo, -1, sizeof(memo)); 14 | // your code here 15 | int result = 0; 16 | for (int i = 0;i < n + 1;i++) memo[i][0] = 0; 17 | for (int j = 0;j < m + 1;j++) memo[0][j] = 0; 18 | 19 | for (int i = 1;i < n + 1;i++) { 20 | for (int j = 1;j < m + 1;j++) { 21 | if (s1[i - 1] == s2[j - 1]) { 22 | memo[i][j] = 1 + memo[i - 1][j - 1]; 23 | result = max(result, memo[i][j]); 24 | } 25 | else { 26 | memo[i][j] = 0; 27 | } 28 | } 29 | } 30 | return result; 31 | } 32 | 33 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /GREEDY/20_min_sum_of_absolute_difference_in_pair_of_2_arrays.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/minimum-sum-absolute-difference-pairs-two-arrays/#:~:text=It%20consists%20of%20two%20steps,result%20to%20the%20sum%20S. 3 | */ 4 | 5 | 6 | // ----------------------------------------------------------------------------------------------------------------------- // 7 | // C++ program to find minimum sum of absolute 8 | // differences of two arrays. 9 | #include 10 | using namespace std; 11 | 12 | // Returns minimum possible pairwise absolute 13 | // difference of two arrays. 14 | long long int findMinSum(int a[], int b[], int n) 15 | { 16 | // Sort both arrays 17 | sort(a, a + n); 18 | sort(b, b + n); 19 | 20 | // Find sum of absolute differences 21 | long long int sum = 0; 22 | for (int i = 0; i < n; i++) 23 | sum = sum + abs(a[i] - b[i]); 24 | 25 | return sum; 26 | } 27 | 28 | // Driver code 29 | int main() 30 | { 31 | // Both a[] and b[] must be of same size. 32 | long long int a[] = { 4, 1, 8, 7 }; 33 | long long int b[] = { 2, 3, 6, 5 }; 34 | int n = sizeof(a) / sizeof(a[0]); 35 | printf("%lld\n", findMinSum(a, b, n)); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /Greedy/20_min_sum_of_absolute_difference_in_pair_of_2_arrays.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/minimum-sum-absolute-difference-pairs-two-arrays/#:~:text=It%20consists%20of%20two%20steps,result%20to%20the%20sum%20S. 3 | */ 4 | 5 | 6 | // ----------------------------------------------------------------------------------------------------------------------- // 7 | // C++ program to find minimum sum of absolute 8 | // differences of two arrays. 9 | #include 10 | using namespace std; 11 | 12 | // Returns minimum possible pairwise absolute 13 | // difference of two arrays. 14 | long long int findMinSum(int a[], int b[], int n) 15 | { 16 | // Sort both arrays 17 | sort(a, a + n); 18 | sort(b, b + n); 19 | 20 | // Find sum of absolute differences 21 | long long int sum = 0; 22 | for (int i = 0; i < n; i++) 23 | sum = sum + abs(a[i] - b[i]); 24 | 25 | return sum; 26 | } 27 | 28 | // Driver code 29 | int main() 30 | { 31 | // Both a[] and b[] must be of same size. 32 | long long int a[] = { 4, 1, 8, 7 }; 33 | long long int b[] = { 2, 3, 6, 5 }; 34 | int n = sizeof(a) / sizeof(a[0]); 35 | printf("%lld\n", findMinSum(a, b, n)); 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /DP/60_matrix_chain_multiplication.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/matrix-chain-multiplication0303/1 3 | sol: https://www.geeksforgeeks.org/matrix-chain-multiplication-dp-8/ 4 | 5 | refer: DP_tut/4_MCM/1_implem.... 6 | */ 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | 10 | class Solution { 11 | public: 12 | int memo[1001][1001]; 13 | int MCM(int arr[], int i, int j) { 14 | if (i >= j) return 0; 15 | 16 | if (memo[i][j] != -1) return memo[i][j]; 17 | 18 | int mn = INT_MAX; 19 | for (int k = i;k < j;k++) { 20 | int temp = MCM(arr, i, k) + MCM(arr, k + 1, j) + (arr[i - 1] * arr[k] * arr[j]); 21 | mn = min(mn, temp); 22 | } 23 | return memo[i][j] = mn; 24 | } 25 | 26 | int matrixMultiplication(int n, int arr[]) 27 | { 28 | // code here 29 | memset(memo, -1, sizeof(memo)); 30 | return MCM(arr, 1, n - 1); 31 | } 32 | }; 33 | 34 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /DP/29_max_path_sum_in_matrix.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/path-in-matrix3805/1 3 | */ 4 | 5 | // ----------------------------------------------------------------------------------------------------------------------- // 6 | 7 | int maximumPath(int n, vector> mat) 8 | { 9 | int omax = 0; 10 | vector> dp(n, vector(n, 0)); 11 | for (int j = 0;j < n;j++) { 12 | dp[0][j] = mat[0][j]; 13 | omax = max(omax, dp[0][j]); 14 | } 15 | 16 | for (int i = 1;i < n;i++) { 17 | for (int j = 0;j < n;j++) { 18 | int a = 0, b = dp[i - 1][j], c = 0; 19 | if (j - 1 >= 0) a = dp[i - 1][j - 1]; 20 | if (j + 1 < n) c = dp[i - 1][j + 1]; 21 | 22 | // here a, b, and c are 3 different path from which current_ele can be added to 23 | // existing sum and can find max_sum. 24 | 25 | dp[i][j] = mat[i][j] + max({ a,b,c }); 26 | omax = max(omax, dp[i][j]); 27 | } 28 | } 29 | return omax; 30 | } 31 | 32 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Disclaimer 2 | 3 | Solution are shared just for the purpose to help beginner, **to revise** and not for credits ✌. 4 | 5 | # Note 6 | 7 | - Respected viewers 🙏, please redirect to solution if and only if you have tried problem few times. 8 | 9 | ## 🔥 I Did It 🔥 10 | 11 | ![lb](https://github.com/shibam120302/Love-Babbar-DSA-Sheet-SOL/blob/main/450%20DSA%20Cracker%20(I%20did%20it).jpg) 12 | 13 | 14 | # Credits 15 | 16 | - question list is shared by YouTuber Love Babbar 17 | 450 questions DSA Cracker Sheet 18 | - How to use this 450 questions DSA Cracker Sheet ? 19 | video 20 | 21 | # Resource Credits 22 | 23 | Here I will list all resource credits 24 | 25 | - geeks for geeks 26 | - Love Babbar 27 | - Aditya Verma 28 | - Pepcoding 29 | 30 | -------------------------------------------------------------------------------- /DP/23_longest_subsequence_adj_diff_1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/longest-subsequence-such-that-difference-between-adjacents-is-one4724/1 3 | 4 | variation of LIS. 5 | 6 | note: it's asked longest not total. 7 | */ 8 | 9 | // ----------------------------------------------------------------------------------------------------------------------- // 10 | 11 | int longestSubsequence(int n, int arr[]) 12 | { 13 | int dp[n]; 14 | dp[0] = 1; 15 | int omax = 1; 16 | for (int i = 1;i < n;i++) { 17 | dp[i] = 1; 18 | for (int j = 0;j < i;j++) { 19 | if (abs(arr[i] - arr[j]) == 1) { 20 | // this time just check if element's diff with current_ele is 1 21 | // and hence add 1 more to that count. 22 | // but why max? : as sometimes it might happen current ele is part of many chain 23 | // hence choose the longest. 24 | dp[i] = max(dp[i], dp[j] + 1); 25 | } 26 | } 27 | omax = max(dp[i], omax); 28 | } 29 | return omax; 30 | } 31 | 32 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /DP/25_max_sum_no_three_are_consequetive.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/maximum-subsequence-sum-such-that-no-three-are-consecutive/ 3 | */ 4 | 5 | // ----------------------------------------------------------------------------------------------------------------------- // 6 | 7 | int maxSumWO3Consec(int arr[], int n) { 8 | int sum[n]; 9 | sum[0] = arr[0]; 10 | sum[1] = arr[0] + arr[1]; 11 | sum[2] = max({ sum[1], arr[2] + sum[0], arr[2] + arr[1] }); 12 | 13 | for (int i = 3;i < n;i++) { 14 | sum[i] = max({ sum[i - 1], arr[i] + sum[i - 2], arr[i] + arr[i - 1] + sum[i - 3] }); 15 | /* 16 | sum[i - 1]: ignoring current_ele 17 | arr[i] + sum[i - 2]: ignoring neighbour ele, 18 | arr[i] + arr[i - 1] + sum[i - 3]: ignoring neighbour's neighbour element 19 | 20 | no other case is possible... 21 | */ 22 | } 23 | return sum[n - 1]; 24 | } 25 | 26 | int main() 27 | { 28 | int arr[] = { 100, 1000 }; 29 | int n = sizeof(arr) / sizeof(arr[0]); 30 | cout << maxSumWO3Consec(arr, n); 31 | return 0; 32 | } 33 | 34 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /DP/51_max_sum_of_pair_with_specific_diff.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/pairs-with-specific-difference1533/1# 3 | */ 4 | 5 | // ----------------------------------------------------------------------------------------------------------------------- // 6 | 7 | int maxSumPairWithDifferenceLessThanK(int arr[], int n, int k) 8 | { 9 | // Your code goes here 10 | sort(arr, arr + n); 11 | int dp[n + 1]; 12 | memset(dp, 0, sizeof(dp)); 13 | dp[0] = 0; // doesn't exist 14 | dp[1] = 0; // single can't be counted 15 | 16 | for (int i = 2;i < n + 1;i++) { 17 | /* 18 | checking if to continue the prev sum ignoring the element for pair OR 19 | making pair with prev ele and adding to the prev's prev sum dp[i-2] and then take out max. 20 | */ 21 | if (arr[i - 1] - arr[i - 2] < k) { 22 | dp[i] = max(dp[i - 1], arr[i - 1] + arr[i - 2] + dp[i - 2]); 23 | } 24 | /* as above condition is not met we r forced to continue with prev sum */ 25 | else dp[i] = dp[i - 1]; 26 | } 27 | return dp[n]; 28 | } 29 | 30 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /GREEDY/13_check_if_its_possible_to_survive_on_island.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/survival/ 3 | 4 | Time Complexity: O(1) 5 | Space Complexity: O(1) 6 | */ 7 | 8 | 9 | 10 | 11 | // ----------------------------------------------------------------------------------------------------------------------- // 12 | // C++ program to find the minimum days on which 13 | // you need to buy food from the shop so that you 14 | // can survive the next S days 15 | #include 16 | using namespace std; 17 | 18 | // function to find the minimum days 19 | void survival(int S, int N, int M) 20 | { 21 | 22 | // If we can not buy at least a week 23 | // supply of food during the first week 24 | // OR We can not buy a day supply of food 25 | // on the first day then we can't survive. 26 | if (((N * 6) < (M * 7) && S > 6) || M > N) 27 | cout << "No\n"; 28 | else { 29 | // If we can survive then we can 30 | // buy ceil(A/N) times where A is 31 | // total units of food required. 32 | int days = (M * S) / N; 33 | if (((M * S) % N) != 0) 34 | days++; 35 | cout << "Yes " << days << endl; 36 | } 37 | } 38 | 39 | // Driver code 40 | int main() 41 | { 42 | int S = 10, N = 16, M = 2; 43 | survival(S, N, M); 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /Greedy/13_check_if_its_possible_to_survive_on_island.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/survival/ 3 | 4 | Time Complexity: O(1) 5 | Space Complexity: O(1) 6 | */ 7 | 8 | 9 | 10 | 11 | // ----------------------------------------------------------------------------------------------------------------------- // 12 | // C++ program to find the minimum days on which 13 | // you need to buy food from the shop so that you 14 | // can survive the next S days 15 | #include 16 | using namespace std; 17 | 18 | // function to find the minimum days 19 | void survival(int S, int N, int M) 20 | { 21 | 22 | // If we can not buy at least a week 23 | // supply of food during the first week 24 | // OR We can not buy a day supply of food 25 | // on the first day then we can't survive. 26 | if (((N * 6) < (M * 7) && S > 6) || M > N) 27 | cout << "No\n"; 28 | else { 29 | // If we can survive then we can 30 | // buy ceil(A/N) times where A is 31 | // total units of food required. 32 | int days = (M * S) / N; 33 | if (((M * S) % N) != 0) 34 | days++; 35 | cout << "Yes " << days << endl; 36 | } 37 | } 38 | 39 | // Driver code 40 | int main() 41 | { 42 | int S = 10, N = 16, M = 2; 43 | survival(S, N, M); 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /DP/24_max_sum_no_two_ele_are_adjacent.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/stickler-theif-1587115621/1 3 | 4 | variation of fibonacci 5 | reference :https://www.geeksforgeeks.org/maximum-sum-such-that-no-two-elements-are-adjacent/ 6 | */ 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | 10 | int FindMaxSum(int arr[], int n) { 11 | int incl = arr[0]; 12 | int excl = 0; 13 | 14 | for (int i = 1; i < n; i++) 15 | { 16 | /* current max excluding i */ 17 | int temp = max(incl, excl); 18 | 19 | /* current max including i */ 20 | incl = excl + arr[i]; 21 | excl = temp; 22 | 23 | // this will take every case like if prev ele was skipped and also current ele is skipped and go on... 24 | } 25 | 26 | /* return max of incl and excl */ 27 | return max(incl, excl); 28 | } 29 | 30 | int main() 31 | { 32 | int arr[] = { 5, 5, 10, 100, 10, 5 }; 33 | int n = sizeof(arr) / sizeof(arr[0]); 34 | printf("%d n", FindMaxSum(arr, n)); 35 | return 0; 36 | } 37 | 38 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /DP/32_partition_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/subset-sum-problem2014/1 3 | 4 | refer: DP_tut/0-1_knapsack/3_equal... 5 | */ 6 | 7 | // ----------------------------------------------------------------------------------------------------------------------- // 8 | 9 | bool subsetSum(int arr[], int n) { 10 | int sum = 0; 11 | for (int i = 0;i < n;i++) { 12 | sum += arr[i]; 13 | } 14 | if (sum % 2) return 0; 15 | sum /= 2; 16 | vector> tabu(n + 1, vector(sum + 1)); 17 | for (int i = 0;i < n + 1;i++) { 18 | tabu[i][0] = true; 19 | } 20 | for (int j = 1;j < sum + 1;j++) { 21 | tabu[0][j] = false; 22 | } 23 | 24 | for (int i = 1;i < n + 1;i++) { 25 | for (int j = 1;j < sum + 1;j++) { 26 | if (arr[i - 1] <= j) { 27 | tabu[i][j] = tabu[i - 1][j - arr[i - 1]] || tabu[i - 1][j]; 28 | } 29 | else tabu[i][j] = tabu[i - 1][j]; 30 | } 31 | } 32 | return tabu[n][sum]; 33 | } 34 | int equalPartition(int N, int arr[]) 35 | { 36 | // code here 37 | return subsetSum(arr, N); 38 | } 39 | 40 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /DP/28_max_length_chain_of_pairs.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/max-length-chain/1# 3 | sol: https://www.geeksforgeeks.org/maximum-length-chain-of-pairs-dp-20/ 4 | 5 | variation of LIS. 6 | 7 | refer: DP_tut/6_LIS/4_maxi... 8 | 9 | note: generally we dont require to sort the pair but to pass the sol. in gfg we have to sort according to first value of every pair. 10 | */ 11 | 12 | // ----------------------------------------------------------------------------------------------------------------------- // 13 | 14 | bool compare(struct val a, struct val b) { 15 | if (a.first == b.first) return a.second < b.second; 16 | return a.first < b.first; 17 | } 18 | int maxChainLen(struct val arr[], int n) 19 | { 20 | sort(arr, arr + n, compare); 21 | int dp[n]; 22 | dp[0] = 1; 23 | int omax = 1; 24 | for (int i = 1;i < n;i++) { 25 | dp[i] = 1; 26 | for (int j = 0;j < i;j++) { 27 | // simple LIS but with Pair 28 | if (arr[i].first > arr[j].second) { 29 | dp[i] = max(dp[i], 1 + dp[j]); 30 | } 31 | } 32 | omax = max(dp[i], omax); 33 | } 34 | return omax; 35 | } 36 | 37 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /GREEDY/19_maximum_sum_of_consecutive_difference_in_circular_array.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/swap-and-maximize5859/1 3 | */ 4 | 5 | 6 | // ----------------------------------------------------------------------------------------------------------------------- // 7 | /* 8 | short and efficient 9 | TC: O(N) 10 | SC: O(1) 11 | */ 12 | long long int maxSum(int arr[], int n) 13 | { 14 | long long int sum = 0; 15 | sort(arr, arr + n); 16 | for (int i = 0; i < n / 2; i++) 17 | { 18 | sum -= (2 * arr[i]); 19 | sum += (2 * arr[n - i - 1]); 20 | } 21 | return sum; 22 | } 23 | 24 | 25 | 26 | 27 | // ----------------------------------------------------------------------------------------------------------------------- // 28 | /* 29 | TC: O(N) 30 | SC: O(N) 31 | */ 32 | typedef long long int lli; 33 | 34 | long long int maxSum(int arr[], int n) 35 | { 36 | sort(arr, arr + n); 37 | 38 | int newArr[n], j = 0; 39 | lli sum = 0; 40 | for (int i = 0; i < (n + 1) / 2; i++) { 41 | newArr[j] = arr[i]; 42 | j += 2; 43 | } 44 | 45 | j = 1; 46 | for (int i = n - 1; i >= n / 2; i--) { 47 | newArr[j] = arr[i]; 48 | j += 2; 49 | } 50 | 51 | for (int i = 0; i < n - 1; i++) { 52 | sum += abs(newArr[i] - newArr[i + 1]); 53 | } 54 | 55 | sum += abs(newArr[0] - newArr[n - 1]); 56 | return sum; 57 | } -------------------------------------------------------------------------------- /Greedy/19_maximum_sum_of_consecutive_difference_in_circular_array.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/swap-and-maximize5859/1 3 | */ 4 | 5 | 6 | // ----------------------------------------------------------------------------------------------------------------------- // 7 | /* 8 | short and efficient 9 | TC: O(N) 10 | SC: O(1) 11 | */ 12 | long long int maxSum(int arr[], int n) 13 | { 14 | long long int sum = 0; 15 | sort(arr, arr + n); 16 | for (int i = 0; i < n / 2; i++) 17 | { 18 | sum -= (2 * arr[i]); 19 | sum += (2 * arr[n - i - 1]); 20 | } 21 | return sum; 22 | } 23 | 24 | 25 | 26 | 27 | // ----------------------------------------------------------------------------------------------------------------------- // 28 | /* 29 | TC: O(N) 30 | SC: O(N) 31 | */ 32 | typedef long long int lli; 33 | 34 | long long int maxSum(int arr[], int n) 35 | { 36 | sort(arr, arr + n); 37 | 38 | int newArr[n], j = 0; 39 | lli sum = 0; 40 | for (int i = 0; i < (n + 1) / 2; i++) { 41 | newArr[j] = arr[i]; 42 | j += 2; 43 | } 44 | 45 | j = 1; 46 | for (int i = n - 1; i >= n / 2; i--) { 47 | newArr[j] = arr[i]; 48 | j += 2; 49 | } 50 | 51 | for (int i = 0; i < n - 1; i++) { 52 | sum += abs(newArr[i] - newArr[i + 1]); 53 | } 54 | 55 | sum += abs(newArr[0] - newArr[n - 1]); 56 | return sum; 57 | } -------------------------------------------------------------------------------- /GREEDY/09_buy_maximum_stock_if_can_be_bought_on_ith_day.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/buy-maximum-stocks-stocks-can-bought-th-day/ 3 | */ 4 | 5 | 6 | // ----------------------------------------------------------------------------------------------------------------------- // 7 | /* 8 | TC: O(N logN) 9 | */ 10 | // CPP program to find maximum number of stocks that 11 | // can be bought with given constraints. 12 | #include 13 | using namespace std; 14 | 15 | // Return the maximum stocks 16 | int buyMaximumProducts(int n, int k, int price[]) 17 | { 18 | vector > v; 19 | 20 | // Making pair of product cost and number 21 | // of day.. 22 | for (int i = 0; i < n; ++i) 23 | v.push_back(make_pair(price[i], i + 1)); 24 | 25 | // Sorting the vector pair. 26 | sort(v.begin(), v.end()); 27 | 28 | // Calculating the maximum number of stock 29 | // count. 30 | int ans = 0; 31 | for (int i = 0; i < n; ++i) { 32 | ans += min(v[i].second, k / v[i].first); 33 | k -= v[i].first * min(v[i].second, 34 | (k / v[i].first)); 35 | } 36 | 37 | return ans; 38 | } 39 | 40 | // Driven Program 41 | int main() 42 | { 43 | int price[] = { 10, 7, 19 }; 44 | int n = sizeof(price) / sizeof(price[0]); 45 | int k = 45; 46 | 47 | cout << buyMaximumProducts(n, k, price) << endl; 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /Greedy/09_buy_maximum_stock_if_can_be_bought_on_ith_day.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/buy-maximum-stocks-stocks-can-bought-th-day/ 3 | */ 4 | 5 | 6 | // ----------------------------------------------------------------------------------------------------------------------- // 7 | /* 8 | TC: O(N logN) 9 | */ 10 | // CPP program to find maximum number of stocks that 11 | // can be bought with given constraints. 12 | #include 13 | using namespace std; 14 | 15 | // Return the maximum stocks 16 | int buyMaximumProducts(int n, int k, int price[]) 17 | { 18 | vector > v; 19 | 20 | // Making pair of product cost and number 21 | // of day.. 22 | for (int i = 0; i < n; ++i) 23 | v.push_back(make_pair(price[i], i + 1)); 24 | 25 | // Sorting the vector pair. 26 | sort(v.begin(), v.end()); 27 | 28 | // Calculating the maximum number of stock 29 | // count. 30 | int ans = 0; 31 | for (int i = 0; i < n; ++i) { 32 | ans += min(v[i].second, k / v[i].first); 33 | k -= v[i].first * min(v[i].second, 34 | (k / v[i].first)); 35 | } 36 | 37 | return ans; 38 | } 39 | 40 | // Driven Program 41 | int main() 42 | { 43 | int price[] = { 10, 7, 19 }; 44 | int n = sizeof(price) / sizeof(price[0]); 45 | int k = 45; 46 | 47 | cout << buyMaximumProducts(n, k, price) << endl; 48 | 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /DP/08_longest_repeated_subsequence.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/longest-repeating-subsequence2004/1 3 | 4 | variation of LCS. 5 | */ 6 | 7 | // ----------------------------------------------------------------------------------------------------------------------- // 8 | 9 | class Solution { 10 | int memo[1001][1001]; 11 | public: 12 | int LCS(string s1, string s2, int n, int m) 13 | { 14 | for (int i = 0;i < n + 1;i++) memo[i][0] = 0; 15 | for (int j = 0;j < m + 1;j++) memo[0][j] = 0; 16 | 17 | for (int i = 1;i < n + 1;i++) { 18 | for (int j = 1;j < m + 1;j++) { 19 | if (s1[i - 1] == s2[j - 1] && i != j) { // crux: add only if position are not same and char is same. 20 | memo[i][j] = 1 + memo[i - 1][j - 1]; 21 | } 22 | else { 23 | memo[i][j] = max(memo[i - 1][j], memo[i][j - 1]); 24 | } 25 | } 26 | } 27 | return memo[n][m]; 28 | } 29 | int LongestRepeatingSubsequence(string str) { 30 | // Code here 31 | return LCS(str, str, str.length(), str.length()); 32 | } 33 | 34 | }; 35 | 36 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /DP/20_LCS_of_3_string.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/lcs-of-three-strings0028/1 3 | */ 4 | 5 | // ----------------------------------------------------------------------------------------------------------------------- // 6 | 7 | int LCSof3(string a, string b, string c, int n, int m, int o) 8 | { 9 | // base cond. 10 | int memo[n + 1][m + 1][o + 1]; 11 | memset(memo, -1, sizeof(memo)); 12 | for (int i = 0;i < n + 1;i++) { 13 | for (int j = 0;j < m + 1;j++) { 14 | for (int k = 0;k < o + 1;k++) { 15 | if (i == 0 || k == 0 || j == 0) { 16 | memo[i][j][k] = 0; 17 | } 18 | } 19 | } 20 | } 21 | 22 | for (int i = 1;i < n + 1;i++) { 23 | for (int j = 1;j < m + 1;j++) { 24 | for (int k = 1;k < o + 1;k++) { 25 | if (a[i - 1] == b[j - 1] && a[i - 1] == c[k - 1]) { 26 | memo[i][j][k] = 1 + memo[i - 1][j - 1][k - 1]; 27 | } 28 | else { 29 | memo[i][j][k] = max({ memo[i - 1][j][k], memo[i][j - 1][k], memo[i][j][k - 1] }); 30 | } 31 | } 32 | } 33 | } 34 | return memo[n][m][o]; 35 | } 36 | 37 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /GREEDY/01_activity_selection_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/n-meetings-in-one-room-1587115620/1 3 | 4 | custom sort function to sort the finishing time. 5 | why static ? 6 | in some online judge platform we have to keep it static so it wont change in lifetime of the program. 7 | */ 8 | 9 | 10 | // ----------------------------------------------------------------------------------------------------------------------- // 11 | bool static compare(pair meeting1, pair meeting2) { 12 | if (meeting1.second == meeting2.second) return meeting1.first < meeting2.first; 13 | return meeting1.second < meeting2.second; 14 | } 15 | 16 | int maxMeetings(int start[], int end[], int n) 17 | { 18 | // using vector pair as we want to sort acc. to the finishing time 19 | vector> timeTable(n); 20 | for (int i = 0;i < n;i++) { 21 | timeTable[i] = { start[i], end[i] }; 22 | } 23 | 24 | sort(timeTable.begin(), timeTable.end(), compare); 25 | 26 | 27 | int temp = INT_MIN; 28 | int meetings = 0; 29 | for (pair p : timeTable) { 30 | // whenever we have starting time larger than prev. finishing time add meeting to room 31 | if (p.first > temp) { 32 | temp = p.second; 33 | meetings++; 34 | } 35 | } 36 | return meetings; 37 | } 38 | -------------------------------------------------------------------------------- /Greedy/01_activity_selection_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/n-meetings-in-one-room-1587115620/1 3 | 4 | custom sort function to sort the finishing time. 5 | why static ? 6 | in some online judge platform we have to keep it static so it wont change in lifetime of the program. 7 | */ 8 | 9 | 10 | // ----------------------------------------------------------------------------------------------------------------------- // 11 | bool static compare(pair meeting1, pair meeting2) { 12 | if (meeting1.second == meeting2.second) return meeting1.first < meeting2.first; 13 | return meeting1.second < meeting2.second; 14 | } 15 | 16 | int maxMeetings(int start[], int end[], int n) 17 | { 18 | // using vector pair as we want to sort acc. to the finishing time 19 | vector> timeTable(n); 20 | for (int i = 0;i < n;i++) { 21 | timeTable[i] = { start[i], end[i] }; 22 | } 23 | 24 | sort(timeTable.begin(), timeTable.end(), compare); 25 | 26 | 27 | int temp = INT_MIN; 28 | int meetings = 0; 29 | for (pair p : timeTable) { 30 | // whenever we have starting time larger than prev. finishing time add meeting to room 31 | if (p.first > temp) { 32 | temp = p.second; 33 | meetings++; 34 | } 35 | } 36 | return meetings; 37 | } 38 | -------------------------------------------------------------------------------- /GREEDY/30_ARRANGE_arranging_amplifiers.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.spoj.com/problems/ARRANGE/ 3 | 4 | video: https://youtu.be/j4AAeH5CPmk 5 | 6 | eg. 4, 3, 2 7 | then 4^(3^(2^1)) will be smaller as compared to 2^(3^(4^1)) 8 | 9 | so in our code it should be like: (1 1 1...) 4 3 2 10 | 11 | hence in our problem pass in descending order. 12 | 13 | we cannot keep 1 at the last positions as anything to the power of 1 will be 1. 14 | */ 15 | 16 | 17 | // ----------------------------------------------------------------------------------------------------------------------- // 18 | #include 19 | using namespace std; 20 | 21 | int main() { 22 | int t; 23 | cin >> t; 24 | while (t--) { 25 | int n; 26 | cin >> n; 27 | vector v; 28 | int one = 0; 29 | for (int i = 0; i < n; i++) { 30 | int x; cin >> x; 31 | if (x == 1) one++; 32 | else v.push_back(x); 33 | } 34 | 35 | sort(v.begin(), v.end(), greater<>()); 36 | 37 | for (int i = 0; i < one; i++) cout << 1 << " "; 38 | 39 | // only single exception where 2^3 is smaller than 3^2 40 | if (n - one == 2 && v[0] == 3 && v[1] == 2) { 41 | cout << "2 3" << endl; 42 | } 43 | else { 44 | for (auto i : v) cout << i << " "; 45 | cout << endl; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /Greedy/30_ARRANGE_arranging_amplifiers.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.spoj.com/problems/ARRANGE/ 3 | 4 | video: https://youtu.be/j4AAeH5CPmk 5 | 6 | eg. 4, 3, 2 7 | then 4^(3^(2^1)) will be smaller as compared to 2^(3^(4^1)) 8 | 9 | so in our code it should be like: (1 1 1...) 4 3 2 10 | 11 | hence in our problem pass in descending order. 12 | 13 | we cannot keep 1 at the last positions as anything to the power of 1 will be 1. 14 | */ 15 | 16 | 17 | // ----------------------------------------------------------------------------------------------------------------------- // 18 | #include 19 | using namespace std; 20 | 21 | int main() { 22 | int t; 23 | cin >> t; 24 | while (t--) { 25 | int n; 26 | cin >> n; 27 | vector v; 28 | int one = 0; 29 | for (int i = 0; i < n; i++) { 30 | int x; cin >> x; 31 | if (x == 1) one++; 32 | else v.push_back(x); 33 | } 34 | 35 | sort(v.begin(), v.end(), greater<>()); 36 | 37 | for (int i = 0; i < one; i++) cout << 1 << " "; 38 | 39 | // only single exception where 2^3 is smaller than 3^2 40 | if (n - one == 2 && v[0] == 3 && v[1] == 2) { 41 | cout << "2 3" << endl; 42 | } 43 | else { 44 | for (auto i : v) cout << i << " "; 45 | cout << endl; 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /BACKTRACKING/10_tug_of_war.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link (little confusing) : https://www.geeksforgeeks.org/tug-of-war/ 3 | 4 | video: https://youtu.be/Q1fLW_zQr3M 5 | */ 6 | 7 | 8 | 9 | // ----------------------------------------------------------------------------------------------------------------------- // 10 | static string allComb = ""; 11 | static int minDiff = INT_MAX; 12 | 13 | 14 | void tugOfWar(int arr[], int n, int idx, vector set1, vector set2, int soset1, int soset2) { 15 | if (idx == n) { 16 | int diff = abs(soset1 - soset2); 17 | 18 | if (diff < minDiff) { 19 | minDiff = diff; 20 | 21 | string ans = ""; 22 | 23 | for (int x : set1) ans += " " + to_string(x); 24 | ans += " " + "$"; 25 | for (int x : set2) ans += " " + to_string(x); 26 | 27 | allComb = ans.substr(1); 28 | } 29 | return; 30 | } 31 | 32 | if (set1.size() < (n + 1) / 2) { 33 | set1.push_back(arr[idx]); 34 | solve(arr, n, idx + 1, set1, set2, soset1 + arr[idx], soset2); 35 | set1.pop_back(); 36 | } 37 | 38 | if (set2.size() < (n + 1) / 2) { 39 | set2.push_back(arr[idx]); 40 | solve(arr, n, idx + 1, set1, set2, soset1, soset2 + arr[idx]); 41 | set2.pop_back(); 42 | } 43 | } 44 | 45 | 46 | int main() { 47 | int arr[] = { 23, 45, -34, 12, 0, 98, -99, 4, 189, -1, 4 }; 48 | int n = sizeof(arr) / sizeof(arr[0]); 49 | 50 | vector set1, set2; 51 | 52 | tugOfWar(arr, n, 0, set1, set2, 0, 0); 53 | return 0; 54 | } 55 | -------------------------------------------------------------------------------- /GREEDY/32_minimum_cost_of_ropes.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/minimum-cost-of-ropes-1587115620/1 3 | 4 | sol: https://www.geeksforgeeks.org/connect-n-ropes-minimum-cost/ 5 | (refer another min-heap code) 6 | */ 7 | 8 | 9 | 10 | // ----------------------------------------------------------------------------------------------------------------------- // 11 | /* 12 | using priority_queue 13 | 14 | Time Complexity: O(nLogn), assuming that we use a O(nLogn) sorting algorithm. 15 | Note that heap operations like insert and extract take O(Logn) time. 16 | Auxiliary Complexity: O(n). 17 | The space required to store the values in min heap 18 | */ 19 | int minCost(int arr[], int n) 20 | { 21 | // Create a priority queue 22 | // https:// www.geeksforgeeks.org/priority-queue-in-cpp-stl/ 23 | // By default 'less' is used which is for decreasing order 24 | // and 'greater' is used for increasing order 25 | priority_queue, greater > pq(arr, arr + n); 26 | 27 | // Initialize result 28 | int res = 0; 29 | 30 | // While size of priority queue is more than 1 31 | while (pq.size() > 1) { 32 | // Extract shortest two ropes from pq 33 | int first = pq.top(); 34 | pq.pop(); 35 | int second = pq.top(); 36 | pq.pop(); 37 | 38 | // Connect the ropes: update result and 39 | // insert the new rope to pq 40 | res += first + second; 41 | pq.push(first + second); 42 | } 43 | 44 | return res; 45 | } -------------------------------------------------------------------------------- /Greedy/32_minimum_cost_of_ropes.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/minimum-cost-of-ropes-1587115620/1 3 | 4 | sol: https://www.geeksforgeeks.org/connect-n-ropes-minimum-cost/ 5 | (refer another min-heap code) 6 | */ 7 | 8 | 9 | 10 | // ----------------------------------------------------------------------------------------------------------------------- // 11 | /* 12 | using priority_queue 13 | 14 | Time Complexity: O(nLogn), assuming that we use a O(nLogn) sorting algorithm. 15 | Note that heap operations like insert and extract take O(Logn) time. 16 | Auxiliary Complexity: O(n). 17 | The space required to store the values in min heap 18 | */ 19 | int minCost(int arr[], int n) 20 | { 21 | // Create a priority queue 22 | // https:// www.geeksforgeeks.org/priority-queue-in-cpp-stl/ 23 | // By default 'less' is used which is for decreasing order 24 | // and 'greater' is used for increasing order 25 | priority_queue, greater > pq(arr, arr + n); 26 | 27 | // Initialize result 28 | int res = 0; 29 | 30 | // While size of priority queue is more than 1 31 | while (pq.size() > 1) { 32 | // Extract shortest two ropes from pq 33 | int first = pq.top(); 34 | pq.pop(); 35 | int second = pq.top(); 36 | pq.pop(); 37 | 38 | // Connect the ropes: update result and 39 | // insert the new rope to pq 40 | res += first + second; 41 | pq.push(first + second); 42 | } 43 | 44 | return res; 45 | } -------------------------------------------------------------------------------- /GREEDY/29_CHOCOLA_choclate.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.spoj.com/problems/CHOCOLA/ 3 | 4 | video: https://youtu.be/9DckVBRzuQU 5 | 6 | refer: 12_min_cost.... 7 | 8 | Note (read this para. in que. carefully): A single break of a part of the chocolate.... 9 | */ 10 | 11 | 12 | // ----------------------------------------------------------------------------------------------------------------------- // 13 | #include 14 | using namespace std; 15 | 16 | int main() { 17 | int t; 18 | cin >> t; 19 | 20 | while (t--) { 21 | int m, n; 22 | cin >> m >> n; 23 | 24 | m--; 25 | n--; 26 | 27 | vector col(m), row(n); 28 | 29 | for (int& a : col) cin >> a; 30 | for (int& b : row) cin >> b; 31 | 32 | sort(col.begin(), col.end(), greater<>()); 33 | sort(row.begin(), row.end(), greater<>()); 34 | 35 | // debug(row); 36 | // debug(col); 37 | 38 | int rcnt = 1, ccnt = 1, i = 0, j = 0, res = 0; 39 | 40 | while (i < m && j < n) { 41 | if (col[i] > row[j]) { 42 | res += rcnt * col[i]; 43 | 44 | ccnt++; 45 | i++; 46 | } 47 | else { 48 | res += ccnt * row[j]; 49 | 50 | j++; 51 | rcnt++; 52 | } 53 | } 54 | 55 | int total = 0; 56 | while (i < m) { 57 | total += col[i++]; 58 | } 59 | res += total * rcnt; 60 | 61 | total = 0; 62 | while (j < n) { 63 | total += row[j++]; 64 | } 65 | res += total * ccnt; 66 | 67 | // return res; 68 | cout << res << endl; 69 | } 70 | 71 | } -------------------------------------------------------------------------------- /Greedy/29_CHOCOLA_choclate.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.spoj.com/problems/CHOCOLA/ 3 | 4 | video: https://youtu.be/9DckVBRzuQU 5 | 6 | refer: 12_min_cost.... 7 | 8 | Note (read this para. in que. carefully): A single break of a part of the chocolate.... 9 | */ 10 | 11 | 12 | // ----------------------------------------------------------------------------------------------------------------------- // 13 | #include 14 | using namespace std; 15 | 16 | int main() { 17 | int t; 18 | cin >> t; 19 | 20 | while (t--) { 21 | int m, n; 22 | cin >> m >> n; 23 | 24 | m--; 25 | n--; 26 | 27 | vector col(m), row(n); 28 | 29 | for (int& a : col) cin >> a; 30 | for (int& b : row) cin >> b; 31 | 32 | sort(col.begin(), col.end(), greater<>()); 33 | sort(row.begin(), row.end(), greater<>()); 34 | 35 | // debug(row); 36 | // debug(col); 37 | 38 | int rcnt = 1, ccnt = 1, i = 0, j = 0, res = 0; 39 | 40 | while (i < m && j < n) { 41 | if (col[i] > row[j]) { 42 | res += rcnt * col[i]; 43 | 44 | ccnt++; 45 | i++; 46 | } 47 | else { 48 | res += ccnt * row[j]; 49 | 50 | j++; 51 | rcnt++; 52 | } 53 | } 54 | 55 | int total = 0; 56 | while (i < m) { 57 | total += col[i++]; 58 | } 59 | res += total * rcnt; 60 | 61 | total = 0; 62 | while (j < n) { 63 | total += row[j++]; 64 | } 65 | res += total * ccnt; 66 | 67 | // return res; 68 | cout << res << endl; 69 | } 70 | 71 | } -------------------------------------------------------------------------------- /TRIE/extra_05_suffix_trie.cpp: -------------------------------------------------------------------------------- 1 | // suffix trie 2 | 3 | 4 | class Node { 5 | public: 6 | char data; 7 | unordered_map m; 8 | bool isTerminal; 9 | 10 | Node(char d) { 11 | data = d; 12 | isTerminal = false; 13 | } 14 | }; 15 | 16 | class Trie { 17 | public: 18 | Node* root; 19 | Trie() { 20 | root = new Node('\0'); 21 | } 22 | 23 | void insert(string word) { 24 | Node* temp = root; 25 | 26 | for (char ch : word) { 27 | if (temp->m.count(ch) == 0) { 28 | temp->m[ch] = new Node(ch); 29 | } 30 | temp = temp->m[ch]; 31 | } 32 | temp->isTerminal = true; 33 | } 34 | 35 | bool search(string word) { 36 | Node* temp = root; 37 | 38 | for (char ch : word) { 39 | if (temp->m.count(ch) == 0) return false; 40 | temp = temp->m[ch]; 41 | } 42 | return temp->isTerminal; 43 | } 44 | 45 | }; 46 | 47 | int main() { 48 | string input = "hello"; 49 | string suffixes[] = { "lo", "ell", "hello" }; 50 | 51 | Trie t; 52 | for (int i = 0;i < input.size();i++) { 53 | t.insert(input.substr(i)); 54 | } 55 | 56 | for (auto i : suffixes) { 57 | if (t.search(i)) { 58 | cout << "Yes, it is present" << endl; 59 | } 60 | else { 61 | cout << "No, it is not present" << endl; 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /DP/55_word_break_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/word-break1352/1 3 | */ 4 | 5 | // ----------------------------------------------------------------------------------------------------------------------- // 6 | 7 | int wordBreak(string A, vector& B) { 8 | set s; 9 | for (string i : B) s.insert(i); 10 | 11 | 12 | int n = A.size(); 13 | int dp[n + 1]; 14 | memset(dp, 0, sizeof(dp)); // to avoid garbage value. 15 | 16 | dp[0] = 1; // empty string is always in dictionary. 17 | 18 | for (int i = 1;i < n + 1;i++) { 19 | for (int j = 0;j < i;j++) { 20 | /* 21 | here dp is of N+1 index based while string is of 0 based 22 | hence dp[0] means empty string while A.substr(0, len) is starting from pos=0. 23 | 24 | so everytime comparison will be like: str=abcd 25 | ("" && "abcd") ("a" && "bcd") ("ab" && "cd") ... 26 | to check every possibilities. 27 | */ 28 | if (dp[j] && s.find(A.substr(j, i - j)) != s.end()) { 29 | // if prev substring's dp is true and new substring is also true then we will set 1 and break. 30 | dp[i] = 1; 31 | break; 32 | } 33 | } 34 | } 35 | return dp[n]; 36 | } 37 | 38 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /GREEDY/23_smallest_subset_with_sum_greater_than_all_other_element.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/smallest-subset-sum-greater-elements/ 3 | */ 4 | 5 | 6 | // ----------------------------------------------------------------------------------------------------------------------- // 7 | /* 8 | another approach 9 | */ 10 | int minElements(int arr[], int n) 11 | { 12 | // calculating HALF of array sum 13 | int sum = 0; 14 | for (int i = 0; i < n; i++) 15 | sum = sum + arr[i]; 16 | 17 | // sort the array in descending order. 18 | sort(arr, arr + n, greater()); 19 | 20 | int otherSum = 0; 21 | int i = 0; 22 | int res = 0; 23 | 24 | while (otherSum <= sum) { 25 | otherSum += arr[i]; 26 | sum -= arr[i]; 27 | res++; 28 | } 29 | return res; 30 | } 31 | 32 | 33 | 34 | 35 | 36 | 37 | // ----------------------------------------------------------------------------------------------------------------------- // 38 | // function to find minimum elements needed. 39 | int minElements(int arr[], int n) 40 | { 41 | // calculating HALF of array sum 42 | int halfSum = 0; 43 | for (int i = 0; i < n; i++) 44 | halfSum = halfSum + arr[i]; 45 | halfSum = halfSum / 2; 46 | 47 | // sort the array in descending order. 48 | sort(arr, arr + n, greater()); 49 | 50 | int res = 0, curr_sum = 0; 51 | for (int i = 0; i < n; i++) { 52 | 53 | curr_sum += arr[i]; 54 | res++; 55 | 56 | // current sum greater than sum 57 | if (curr_sum > halfSum) 58 | return res; 59 | } 60 | return res; 61 | } 62 | -------------------------------------------------------------------------------- /Greedy/23_smallest_subset_with_sum_greater_than_all_other_element.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/smallest-subset-sum-greater-elements/ 3 | */ 4 | 5 | 6 | // ----------------------------------------------------------------------------------------------------------------------- // 7 | /* 8 | another approach 9 | */ 10 | int minElements(int arr[], int n) 11 | { 12 | // calculating HALF of array sum 13 | int sum = 0; 14 | for (int i = 0; i < n; i++) 15 | sum = sum + arr[i]; 16 | 17 | // sort the array in descending order. 18 | sort(arr, arr + n, greater()); 19 | 20 | int otherSum = 0; 21 | int i = 0; 22 | int res = 0; 23 | 24 | while (otherSum <= sum) { 25 | otherSum += arr[i]; 26 | sum -= arr[i]; 27 | res++; 28 | } 29 | return res; 30 | } 31 | 32 | 33 | 34 | 35 | 36 | 37 | // ----------------------------------------------------------------------------------------------------------------------- // 38 | // function to find minimum elements needed. 39 | int minElements(int arr[], int n) 40 | { 41 | // calculating HALF of array sum 42 | int halfSum = 0; 43 | for (int i = 0; i < n; i++) 44 | halfSum = halfSum + arr[i]; 45 | halfSum = halfSum / 2; 46 | 47 | // sort the array in descending order. 48 | sort(arr, arr + n, greater()); 49 | 50 | int res = 0, curr_sum = 0; 51 | for (int i = 0; i < n; i++) { 52 | 53 | curr_sum += arr[i]; 54 | res++; 55 | 56 | // current sum greater than sum 57 | if (curr_sum > halfSum) 58 | return res; 59 | } 60 | return res; 61 | } 62 | -------------------------------------------------------------------------------- /DP/19_LCS_space_optimized.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/space-optimized-solution-lcs/ 3 | 4 | here we can optimize the space complexity. how? 5 | ans: If we observe in our LCS previous code (dp_tut/3_LCS/1_imp...) we only require i-1's value while calculating the 6 | current value hence we can do this the same in array having 2 row. 7 | 8 | */ 9 | 10 | // ----------------------------------------------------------------------------------------------------------------------- // 11 | 12 | int lcs(string& X, string& Y) 13 | { 14 | 15 | // Find lengths of two strings 16 | int m = X.length(), n = Y.length(); 17 | 18 | int L[2][n + 1]; 19 | 20 | // Binary index, used to 21 | // index current row and 22 | // previous row. 23 | bool bi; 24 | 25 | for (int i = 0; i <= m; i++) 26 | { 27 | 28 | // Compute current 29 | // binary index 30 | bi = i & 1; // or we can use i%2 everywhere both are same. 31 | 32 | for (int j = 0; j <= n; j++) 33 | { 34 | if (i == 0 || j == 0) 35 | L[bi][j] = 0; 36 | 37 | else if (X[i - 1] == Y[j - 1]) 38 | L[bi][j] = L[1 - bi][j - 1] + 1; 39 | 40 | else 41 | L[bi][j] = max(L[1 - bi][j], 42 | L[bi][j - 1]); 43 | } 44 | } 45 | 46 | return L[bi][n]; 47 | } 48 | 49 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /DP/22_count_all_subsequence_product_less_than_k.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/count-subsequences-product-less-k/ 3 | video: https://www.youtube.com/watch?v=OBLvQwkhej0 4 | 5 | variation of 0/1 knapsack. 6 | */ 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | 10 | int LIS_product(int arr[], int n, int k) { 11 | int dp[k + 1][n + 1]; 12 | for (int j = 0;j < n + 1;j++) dp[0][j] = 0; 13 | // k=0 then no element can make this product as n>=1; 14 | for (int i = 0;i < k + 1;i++) dp[i][0] = 0; 15 | // n=0 there exist no element to compare 16 | 17 | 18 | for (int i = 1;i < k + 1;i++) { 19 | for (int j = 1;j < n + 1;j++) { 20 | dp[i][j] = dp[i][j - 1]; 21 | // add the prev total count. 22 | 23 | if (arr[j - 1] <= i) { 24 | dp[i][j] += dp[i / arr[j - 1]][j - 1] + 1; 25 | /* 26 | here as we know current_element(arr[j-1]) is less than product_required(i) 27 | now we will find such existing_product whose ans is less, but how much? ans: i/arr[j-1] atleast current_element times. 28 | why +1: as after finding above no. we have to add 1 for current pair it will make. 29 | */ 30 | } 31 | } 32 | } 33 | dp[k][n]; 34 | } 35 | 36 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /DP/14_friend_pairing_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/friends-pairing-problem5425/1 3 | 4 | variation of 1/0 knapsack. 5 | 6 | */ 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | 10 | // memoization 11 | const long long mod = 1e9 + 7; 12 | vector dp; 13 | long long recur(long long n) { 14 | 15 | if (dp[n] != -1) return dp[n]; 16 | 17 | 18 | // if nth person pairs with someone then have (n-1) choices hence (n-1)*f(n-2) 19 | // why n-2 as nth person has already paired with 1 out of (n-1) so now pair with other n-2. 20 | if (n > 2) return dp[n] = (recur(n - 1) % mod) + ((n - 1) * (recur(n - 2) % mod) % mod); 21 | else return dp[n] = n; 22 | } 23 | long long countFriendsPairings(long long n) 24 | { 25 | // memset(dp, -1, sizeof(dp)); 26 | dp = vector(n + 1, -1); 27 | return recur(n) % mod; 28 | } 29 | 30 | // ----------------------------------------------------------------------------------------------------------------------- // 31 | 32 | // tabulation 33 | int countFriendsPairings(int n) { 34 | long long dp[n + 1]; 35 | memset(dp, -1, sizeof(dp)); 36 | for (int i = 1;i < n + 1;i++) { 37 | if (i <= 2) dp[i] = i; 38 | else dp[i] = (dp[i - 1] + ((i - 1) * dp[i - 2]) % mod) % mod; 39 | } 40 | return dp[n]; 41 | } 42 | 43 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /DP/44_optimal_strategy_for_game.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/optimal-strategy-for-a-game-1587115620/1 3 | 4 | video: https://www.youtube.com/watch?v=ww4V7vRIzSk 5 | 6 | when we aim to make opponent fail greedy will work 7 | but when to aim for make opponent fail + optimally win we use DP. 8 | 9 | 10 | video will be more helpful in this problem. 11 | 12 | here we are filling in diagonal manner 13 | 14 | why? 15 | as we want gap (length between 0, n-1) at a time constant but increasing 1 at a time 16 | also we want i and j to increase by 1 both at a time as both us and opponent will be making choices. 17 | 18 | */ 19 | 20 | // ----------------------------------------------------------------------------------------------------------------------- // 21 | 22 | long long maximumAmount(int arr[], int n) 23 | { 24 | int dp[n][n]; 25 | memset(dp, 0, sizeof(dp)); 26 | 27 | 28 | for (int gap = 0;gap < n;gap++) { 29 | for (int i = 0, j = gap;j < n;j++, i++) { 30 | if (gap == 0) dp[i][j] = arr[i]; 31 | else if (gap == 1) dp[i][j] = max(arr[i], arr[j]); 32 | else { 33 | int a = arr[i] + min(dp[i + 1][j - 1], dp[i + 2][j]); 34 | int b = arr[j] + min(dp[i][j - 2], dp[i + 1][j - 1]); 35 | dp[i][j] = max(a, b); 36 | } 37 | } 38 | } 39 | return dp[0][n - 1]; 40 | } 41 | 42 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /TRIE/06_print_unique_rows_in_given_boolean_matrix.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/unique-rows-in-boolean-matrix/1# 3 | 4 | sol: https://www.geeksforgeeks.org/print-unique-rows/ 5 | refer other solution as well 6 | */ 7 | 8 | 9 | 10 | // ----------------------------------------------------------------------------------------------------------------------- // 11 | /* 12 | using Trie 13 | 14 | here search TC will become O(M) which is best. 15 | */ 16 | class Node { 17 | public: 18 | Node* child[2]; 19 | bool isEnd; 20 | }; 21 | 22 | Node* newNode() { 23 | Node* temp = new Node(); 24 | temp->child[1] = temp->child[0] = NULL; 25 | temp->isEnd = 0; 26 | return temp; 27 | } 28 | 29 | bool insert(Node** root, int M[MAX][MAX], int row, int col, int COL) { 30 | if ((*root) == NULL) (*root) = newNode(); 31 | 32 | if (col < COL) { 33 | insert(&((*root)->child[M[row][col]]), M, row, col + 1, COL); 34 | } 35 | else { 36 | if (!(*root)->isEnd) return (*root)->isEnd = 1; 37 | return 0; 38 | } 39 | } 40 | 41 | vector> uniqueRow(int M[MAX][MAX], int row, int col) 42 | { 43 | Node* root = newNode(); 44 | int i; 45 | vector> ans; 46 | 47 | for (i = 0;i < row;i++) { 48 | if (insert(&root, M, i, 0, col)) { 49 | // insert in ans vector 50 | vector temp; 51 | for (int j = 0;j < col;j++) temp.push_back(M[i][j]); 52 | ans.push_back(temp); 53 | } 54 | } 55 | 56 | return ans; 57 | } -------------------------------------------------------------------------------- /GREEDY/02_job_sequencing_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/job-sequencing-problem-1587115620/1 3 | 4 | logic: 5 | 1. sort by profit so that we can prioritize the best 6 | 2. now for every job find : 7 | a. if the current job is empty then fill it 8 | b. if not the current job then find the job slot which is empty and having deadline less than current 9 | 10 | warning: we cannot the replace the filled job as if the job exist for that deadline then we have to fill it. 11 | */ 12 | 13 | 14 | 15 | // ----------------------------------------------------------------------------------------------------------------------- // 16 | bool static compare(Job a, Job b) 17 | { 18 | return (a.profit > b.profit); 19 | } 20 | 21 | class Solution 22 | { 23 | public: 24 | //Function to find the maximum profit and the number of jobs done. 25 | vector JobScheduling(Job arr[], int n) 26 | { 27 | sort(arr, arr + n, compare); 28 | int a[n + 1]; 29 | memset(a, 0, sizeof(a)); 30 | for (int i = 0;i < n;i++) { 31 | for (int j = min(arr[i].dead, n);j > 0;j--) { 32 | if (a[j] == 0) { 33 | a[j] = arr[i].profit; 34 | break; 35 | } 36 | } 37 | } 38 | int cnt = 0, ans = 0; 39 | for (int i = 1;i <= n;i++) { 40 | if (a[i] != 0) { 41 | cnt++; 42 | ans += a[i]; 43 | } 44 | } 45 | return { cnt, ans }; 46 | } 47 | }; -------------------------------------------------------------------------------- /Greedy/02_job_sequencing_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/job-sequencing-problem-1587115620/1 3 | 4 | logic: 5 | 1. sort by profit so that we can prioritize the best 6 | 2. now for every job find : 7 | a. if the current job is empty then fill it 8 | b. if not the current job then find the job slot which is empty and having deadline less than current 9 | 10 | warning: we cannot the replace the filled job as if the job exist for that deadline then we have to fill it. 11 | */ 12 | 13 | 14 | 15 | // ----------------------------------------------------------------------------------------------------------------------- // 16 | bool static compare(Job a, Job b) 17 | { 18 | return (a.profit > b.profit); 19 | } 20 | 21 | class Solution 22 | { 23 | public: 24 | //Function to find the maximum profit and the number of jobs done. 25 | vector JobScheduling(Job arr[], int n) 26 | { 27 | sort(arr, arr + n, compare); 28 | int a[n + 1]; 29 | memset(a, 0, sizeof(a)); 30 | for (int i = 0;i < n;i++) { 31 | for (int j = min(arr[i].dead, n);j > 0;j--) { 32 | if (a[j] == 0) { 33 | a[j] = arr[i].profit; 34 | break; 35 | } 36 | } 37 | } 38 | int cnt = 0, ans = 0; 39 | for (int i = 1;i <= n;i++) { 40 | if (a[i] != 0) { 41 | cnt++; 42 | ans += a[i]; 43 | } 44 | } 45 | return { cnt, ans }; 46 | } 47 | }; -------------------------------------------------------------------------------- /GREEDY/10_max_min_amount_to_buy_all_candy.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/shop-in-candy-store1145/1 3 | 4 | sol: https://www.geeksforgeeks.org/find-minimum-maximum-amount-buy-n-candies/ 5 | */ 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | /* 10 | TC: O(N log N) 11 | */ 12 | int findMinimum(int arr[], int n, int k) 13 | { 14 | int res = 0; 15 | for (int i = 0; i < n; i++) { 16 | // Buy current candy 17 | res += arr[i]; 18 | 19 | // And take k candies for free 20 | // from the last 21 | n = n - k; 22 | } 23 | return res; 24 | } 25 | 26 | int findMaximum(int arr[], int n, int k) 27 | { 28 | int res = 0, index = 0; 29 | 30 | for (int i = n - 1; i >= index; i--) 31 | { 32 | // Buy candy with maximum amount 33 | res += arr[i]; 34 | 35 | // And get k candies for free from 36 | // the starting 37 | index += k; 38 | } 39 | return res; 40 | } 41 | 42 | 43 | 44 | 45 | // ----------------------------------------------------------------------------------------------------------------------- // 46 | /* 47 | TC: O(N logN) 48 | */ 49 | vector candyStore(int candies[], int N, int K) 50 | { 51 | sort(candies, candies + N); 52 | 53 | // get index for 54 | int total_idx = N / (K + 1); 55 | if (N % (K + 1)) total_idx++; 56 | 57 | total_idx = min(total_idx, N); 58 | 59 | int mn = 0, mx = 0; 60 | 61 | for (int i = 0; i < total_idx; i++) { 62 | mn += candies[i]; 63 | } 64 | for (int i = N - 1; i >= N - total_idx; i--) { 65 | mx += candies[i]; 66 | } 67 | 68 | return { mn, mx }; 69 | } -------------------------------------------------------------------------------- /Greedy/10_max_min_amount_to_buy_all_candy.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/shop-in-candy-store1145/1 3 | 4 | sol: https://www.geeksforgeeks.org/find-minimum-maximum-amount-buy-n-candies/ 5 | */ 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | /* 10 | TC: O(N log N) 11 | */ 12 | int findMinimum(int arr[], int n, int k) 13 | { 14 | int res = 0; 15 | for (int i = 0; i < n; i++) { 16 | // Buy current candy 17 | res += arr[i]; 18 | 19 | // And take k candies for free 20 | // from the last 21 | n = n - k; 22 | } 23 | return res; 24 | } 25 | 26 | int findMaximum(int arr[], int n, int k) 27 | { 28 | int res = 0, index = 0; 29 | 30 | for (int i = n - 1; i >= index; i--) 31 | { 32 | // Buy candy with maximum amount 33 | res += arr[i]; 34 | 35 | // And get k candies for free from 36 | // the starting 37 | index += k; 38 | } 39 | return res; 40 | } 41 | 42 | 43 | 44 | 45 | // ----------------------------------------------------------------------------------------------------------------------- // 46 | /* 47 | TC: O(N logN) 48 | */ 49 | vector candyStore(int candies[], int N, int K) 50 | { 51 | sort(candies, candies + N); 52 | 53 | // get index for 54 | int total_idx = N / (K + 1); 55 | if (N % (K + 1)) total_idx++; 56 | 57 | total_idx = min(total_idx, N); 58 | 59 | int mn = 0, mx = 0; 60 | 61 | for (int i = 0; i < total_idx; i++) { 62 | mn += candies[i]; 63 | } 64 | for (int i = N - 1; i >= N - total_idx; i--) { 65 | mx += candies[i]; 66 | } 67 | 68 | return { mn, mx }; 69 | } -------------------------------------------------------------------------------- /GREEDY/28_picking_up_chicks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.spoj.com/problems/GCJ101BB/ 3 | 4 | video: https://youtu.be/vrRWIbhGK7o 5 | */ 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | #include 10 | using namespace std; 11 | #define endl "\n" 12 | 13 | int main() 14 | { 15 | long long int t, j; 16 | cin >> t; 17 | for (j = 1;j <= t;++j) 18 | { 19 | long long int n, k, b, time; 20 | cin >> n >> k >> b >> time; 21 | 22 | long long int x[n], v[n], i; 23 | for (i = 0;i < n;++i) 24 | cin >> x[i]; 25 | 26 | for (i = 0;i < n;++i) 27 | cin >> v[i]; 28 | 29 | int count = 0, swaps = 0, penalty = 0; 30 | for (i = n - 1;i >= 0;--i) 31 | { 32 | int distance_needed = b - x[i]; 33 | int distance_possible = v[i] * time; 34 | 35 | // chick will be able to reach barn 36 | if (distance_possible >= distance_needed) 37 | { 38 | count++; 39 | // if (penalty > 0) 40 | swaps += penalty; 41 | } 42 | // chick will not be able to reach 43 | else 44 | // hence penalty increases 45 | penalty++; 46 | 47 | if (count >= k) 48 | break; 49 | } 50 | 51 | if (count >= k) 52 | cout << "Case #" << j << ": " << swaps << endl; 53 | 54 | else 55 | cout << "Case #" << j << ": " << "IMPOSSIBLE" << endl; 56 | } 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /Greedy/28_picking_up_chicks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.spoj.com/problems/GCJ101BB/ 3 | 4 | video: https://youtu.be/vrRWIbhGK7o 5 | */ 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | #include 10 | using namespace std; 11 | #define endl "\n" 12 | 13 | int main() 14 | { 15 | long long int t, j; 16 | cin >> t; 17 | for (j = 1;j <= t;++j) 18 | { 19 | long long int n, k, b, time; 20 | cin >> n >> k >> b >> time; 21 | 22 | long long int x[n], v[n], i; 23 | for (i = 0;i < n;++i) 24 | cin >> x[i]; 25 | 26 | for (i = 0;i < n;++i) 27 | cin >> v[i]; 28 | 29 | int count = 0, swaps = 0, penalty = 0; 30 | for (i = n - 1;i >= 0;--i) 31 | { 32 | int distance_needed = b - x[i]; 33 | int distance_possible = v[i] * time; 34 | 35 | // chick will be able to reach barn 36 | if (distance_possible >= distance_needed) 37 | { 38 | count++; 39 | // if (penalty > 0) 40 | swaps += penalty; 41 | } 42 | // chick will not be able to reach 43 | else 44 | // hence penalty increases 45 | penalty++; 46 | 47 | if (count >= k) 48 | break; 49 | } 50 | 51 | if (count >= k) 52 | cout << "Case #" << j << ": " << swaps << endl; 53 | 54 | else 55 | cout << "Case #" << j << ": " << "IMPOSSIBLE" << endl; 56 | } 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /GREEDY/25_DEFKIN_defence_of_kingdom.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.spoj.com/proyCorrlems/DEFKIN/ 3 | 4 | video: https://youtu.be/fk1yIirivEo 5 | */ 6 | 7 | 8 | 9 | // ----------------------------------------------------------------------------------------------------------------------- // 10 | #include 11 | using namespace std; 12 | 13 | int main() { 14 | 15 | int t; 16 | cin >> t; 17 | while (t--) { 18 | int width, height, points; 19 | cin >> width >> height >> points; 20 | vector xCorr; 21 | vector yCorr; 22 | 23 | // as to compare with the base boundary 24 | xCorr.push_back(0); 25 | yCorr.push_back(0); 26 | 27 | for (int i = 0;i < points;i++) { 28 | int x, y; 29 | cin >> x >> y; 30 | xCorr.push_back(x); 31 | yCorr.push_back(y); 32 | } 33 | 34 | // as to compare with the extreme boundary as well 35 | xCorr.push_back(width + 1); 36 | yCorr.push_back(height + 1); 37 | 38 | 39 | // as increasing order will help to get immediate difference 40 | sort(xCorr.begin(), xCorr.end()); 41 | sort(yCorr.begin(), yCorr.end()); 42 | 43 | 44 | int mx = 0, my = 0; 45 | for (int i = 0;i < xCorr.size() - 1;i++) { 46 | // here we do extra -1 as we want gap between them 47 | 48 | // maximum gap in x - axis 49 | mx = max(mx, xCorr[i + 1] - xCorr[i] - 1); 50 | 51 | // maximum gap in y - axis 52 | my = max(my, yCorr[i + 1] - yCorr[i] - 1); 53 | } 54 | cout << mx * my << endl; 55 | } 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /Greedy/25_DEFKIN_defence_of_kingdom.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.spoj.com/proyCorrlems/DEFKIN/ 3 | 4 | video: https://youtu.be/fk1yIirivEo 5 | */ 6 | 7 | 8 | 9 | // ----------------------------------------------------------------------------------------------------------------------- // 10 | #include 11 | using namespace std; 12 | 13 | int main() { 14 | 15 | int t; 16 | cin >> t; 17 | while (t--) { 18 | int width, height, points; 19 | cin >> width >> height >> points; 20 | vector xCorr; 21 | vector yCorr; 22 | 23 | // as to compare with the base boundary 24 | xCorr.push_back(0); 25 | yCorr.push_back(0); 26 | 27 | for (int i = 0;i < points;i++) { 28 | int x, y; 29 | cin >> x >> y; 30 | xCorr.push_back(x); 31 | yCorr.push_back(y); 32 | } 33 | 34 | // as to compare with the extreme boundary as well 35 | xCorr.push_back(width + 1); 36 | yCorr.push_back(height + 1); 37 | 38 | 39 | // as increasing order will help to get immediate difference 40 | sort(xCorr.begin(), xCorr.end()); 41 | sort(yCorr.begin(), yCorr.end()); 42 | 43 | 44 | int mx = 0, my = 0; 45 | for (int i = 0;i < xCorr.size() - 1;i++) { 46 | // here we do extra -1 as we want gap between them 47 | 48 | // maximum gap in x - axis 49 | mx = max(mx, xCorr[i + 1] - xCorr[i] - 1); 50 | 51 | // maximum gap in y - axis 52 | my = max(my, yCorr[i + 1] - yCorr[i] - 1); 53 | } 54 | cout << mx * my << endl; 55 | } 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /DP/52_Maximum_size_square_sub-matrix_with_all_1.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/largest-square-formed-in-a-matrix/0 3 | 4 | video: https://www.youtube.com/watch?v=UagRoA3C5VQ&ab_channel=Pepcoding 5 | */ 6 | 7 | // ----------------------------------------------------------------------------------------------------------------------- // 8 | 9 | class Solution { 10 | public: 11 | int maxSquare(int n, int m, vector> mat) { 12 | int dp[n + 1][m + 1]; 13 | memset(dp, 0, sizeof(dp)); 14 | 15 | /* if 1st col. and 1st row put as it is as they won't be able to make square */ 16 | for (int i = 0;i < n;i++) { 17 | dp[i][0] = mat[i][0]; 18 | } 19 | for (int j = 0;j < m;j++) { 20 | dp[0][j] = mat[0][j]; 21 | } 22 | int mx = INT_MIN; 23 | for (int i = 1;i < n;i++) { 24 | for (int j = 1;j < m;j++) { 25 | 26 | /* here if any of the neighbour is 0 then size will be 1(itself) as we have to find matrix with all 1. 27 | hence for that reason we have to take min of all the neighbour square in mat. 28 | */ 29 | if (mat[i][j] == 1) { 30 | dp[i][j] = 1 + min({ dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1] }); 31 | } 32 | // if current ele is 0 then it's any sub-square matrix won't counted. 33 | else dp[i][j] = 0; 34 | mx = max(mx, dp[i][j]); 35 | } 36 | } 37 | return (mx == INT_MIN) ? 1 : mx; 38 | } 39 | }; 40 | 41 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /DP/02_equal_subset-sum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/subset-sum-problem2014/1 3 | 4 | for memoization go to DP_tut/1_0-1_knapsack/2_subset... its just variation 5 | */ 6 | 7 | // ----------------------------------------------------------------------------------------------------------------------- // 8 | 9 | // tabulation 10 | class Solution { 11 | public: 12 | bool subsetSum(int arr[], int n, int sum) { 13 | vector> tabu(n + 1, vector(sum + 1)); 14 | for (int i = 0;i < n + 1;i++) { 15 | tabu[i][0] = true; 16 | } 17 | for (int j = 1;j < sum + 1;j++) { 18 | tabu[0][j] = false; 19 | } 20 | 21 | for (int i = 1;i < n + 1;i++) { 22 | for (int j = 1;j < sum + 1;j++) { 23 | if (arr[i - 1] <= j) { 24 | tabu[i][j] = tabu[i - 1][j - arr[i - 1]] || tabu[i - 1][j]; 25 | } 26 | else tabu[i][j] = tabu[i - 1][j]; 27 | } 28 | } 29 | return tabu[n][sum]; 30 | } 31 | int equalPartition(int N, int arr[]) 32 | { 33 | int sum = 0; 34 | for (int i = 0;i < N;i++) { 35 | sum += arr[i]; 36 | } 37 | 38 | // this is crux of whole problem 39 | // if sum found is odd then its not possible to divide the array in 2 subset 40 | // and if sum found is even then we can use subset sum problem/implemetation to complete rest of the problem. 41 | if (sum % 2) return 0; 42 | sum /= 2; 43 | 44 | return subsetSum(arr, N, sum); 45 | } 46 | 47 | }; 48 | 49 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /GREEDY/27_GERGOVIA_wine_trading_in_gergovia.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.spoj.com/problems/GERGOVIA/ 3 | 4 | video: https://youtu.be/PJdOUDWYstY 5 | */ 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | #include 10 | using namespace std; 11 | 12 | int main() { 13 | long long int n; 14 | cin >> n; 15 | while (true) { 16 | cin >> n; 17 | if (n == 0) break; 18 | 19 | long long int a[n]; 20 | for (long long int i = 0; i < n; i++) cin >> a[i]; 21 | 22 | vector> sell, buy; 23 | 24 | // segregate acc. to seller and buyer 25 | for (long long int i = 0;i < n;i++) { 26 | if (a[i] > 0) buy.push_back({ a[i], i }); 27 | else sell.push_back({ a[i], i }); 28 | } 29 | 30 | long long int currBuyer = 0, currSeller = 0; 31 | long long int ans = 0; 32 | 33 | while (currBuyer < buy.size() && currSeller < sell.size()) { 34 | long long int x = min(buy[currBuyer].first, -sell[currSeller].first); 35 | 36 | // to calculate final value after wine is bought 37 | buy[currBuyer].first -= x; 38 | sell[currSeller].first += x; 39 | 40 | // many times the cost will be ... 41 | long long int times = abs(buy[currBuyer].second - sell[currSeller].second); 42 | 43 | ans += (times * x); 44 | 45 | // to move on to new buyer or seller 46 | if (buy[currBuyer].first == 0) currBuyer++; 47 | if (sell[currSeller].first == 0) currSeller++; 48 | } 49 | 50 | cout << ans << endl; 51 | } 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /Greedy/27_GERGOVIA_wine_trading_in_gergovia.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.spoj.com/problems/GERGOVIA/ 3 | 4 | video: https://youtu.be/PJdOUDWYstY 5 | */ 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | #include 10 | using namespace std; 11 | 12 | int main() { 13 | long long int n; 14 | cin >> n; 15 | while (true) { 16 | cin >> n; 17 | if (n == 0) break; 18 | 19 | long long int a[n]; 20 | for (long long int i = 0; i < n; i++) cin >> a[i]; 21 | 22 | vector> sell, buy; 23 | 24 | // segregate acc. to seller and buyer 25 | for (long long int i = 0;i < n;i++) { 26 | if (a[i] > 0) buy.push_back({ a[i], i }); 27 | else sell.push_back({ a[i], i }); 28 | } 29 | 30 | long long int currBuyer = 0, currSeller = 0; 31 | long long int ans = 0; 32 | 33 | while (currBuyer < buy.size() && currSeller < sell.size()) { 34 | long long int x = min(buy[currBuyer].first, -sell[currSeller].first); 35 | 36 | // to calculate final value after wine is bought 37 | buy[currBuyer].first -= x; 38 | sell[currSeller].first += x; 39 | 40 | // many times the cost will be ... 41 | long long int times = abs(buy[currBuyer].second - sell[currSeller].second); 42 | 43 | ans += (times * x); 44 | 45 | // to move on to new buyer or seller 46 | if (buy[currBuyer].first == 0) currBuyer++; 47 | if (sell[currSeller].first == 0) currSeller++; 48 | } 49 | 50 | cout << ans << endl; 51 | } 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /BACKTRACKING/03_word_break_problem_using_backtracking.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/word-break-part-23249/1 3 | 4 | video: https://youtu.be/LmHWIsBQBU4 5 | 6 | sol (DP solution): https://www.geeksforgeeks.org/word-break-problem-dp-32-set-2/ 7 | */ 8 | 9 | 10 | 11 | 12 | // ----------------------------------------------------------------------------------------------------------------------- // 13 | /* 14 | TC: O(N * N), one for to iterate the string and other to recursively perform again 15 | SC: O(dict.size()) 16 | */ 17 | 18 | // to access dict. word in O(1) 19 | unordered_set dict; 20 | // to push the final ans. 21 | vector allAns; 22 | 23 | void backtracking(string str, string ans) { 24 | // it means we reach the end for the certain combination 25 | if (str.size() == 0) { 26 | // to remove the extra space at the end we did ans.size()-1 27 | allAns.push_back(ans.substr(0, ans.size() - 1)); 28 | return; 29 | } 30 | 31 | for (int i = 0;i < str.size();i++) { 32 | // get left sub-string each time 33 | string left = str.substr(0, i + 1); 34 | 35 | // if left sub-string is present 36 | if (dict.find(left) != dict.end()) { 37 | 38 | // find the right sub-string and try it recursively to break; 39 | string right = str.substr(i + 1); 40 | backtracking(right, ans + left + " "); 41 | } 42 | } 43 | } 44 | 45 | vector wordBreak(int n, vector& wordDict, string s) 46 | { 47 | dict.clear(); 48 | allAns.clear(); 49 | 50 | for (string curr : wordDict) dict.insert(curr); 51 | 52 | // trying out every break possible 53 | backtracking(s, ""); 54 | 55 | return allAns; 56 | } -------------------------------------------------------------------------------- /DP/46_all_count_palindromic_subsequence.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/count-palindromic-subsequences/1 3 | 4 | video: https://www.youtube.com/watch?v=NdpolO4sM3k 5 | video: https://www.youtube.com/watch?v=YHSjvswCXC8 6 | 7 | very useful source: https://www.geeksforgeeks.org/count-palindromic-subsequence-given-string/ 8 | 9 | */ 10 | 11 | // ----------------------------------------------------------------------------------------------------------------------- // 12 | 13 | const long long mod = 1e9 + 7; 14 | long long dp[1002][1002]; 15 | int helper(string& s, int i, int j) { 16 | if (i > j) { 17 | return 0; 18 | } 19 | if (i == j) { 20 | return 1; 21 | } 22 | if (dp[i][j] != -1) { 23 | return dp[i][j] % mod; 24 | } 25 | if (s[i] == s[j]) { 26 | /* why still i+1,j and i,j-1? 27 | ans: to understand this go to: https://media.geeksforgeeks.org/wp-content/uploads/20190804162927/00011.jpg 28 | */ 29 | 30 | dp[i][j] = (1 + helper(s, i + 1, j) % mod + helper(s, i, j - 1) % mod) % mod; 31 | } 32 | else { 33 | /* 34 | while here - (i+1, j-1) as.. 35 | here let's take abc then 36 | a b and b c hence b is repeating twice which is irrelavant hence deduct that.s 37 | */ 38 | dp[i][j] = (helper(s, i, j - 1) % mod + helper(s, i + 1, j) % mod - helper(s, i + 1, j - 1) % mod) % mod; 39 | } 40 | return dp[i][j] % mod; 41 | } 42 | long long int countPS(string str) 43 | { 44 | //Your code here 45 | memset(dp, -1, sizeof(dp)); 46 | return helper(str, 0, str.size() - 1) % mod; 47 | } 48 | 49 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /GREEDY/08_minimum_platform_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/minimum-platforms-1587115620/1 3 | 4 | sol: https://www.geeksforgeeks.org/minimum-number-platforms-required-railwaybus-station/ 5 | */ 6 | 7 | 8 | 9 | // ----------------------------------------------------------------------------------------------------------------------- // 10 | /* 11 | TC: O(N * logN) 12 | SC: O(1) 13 | */ 14 | 15 | // Program to find minimum number of platforms 16 | // required on a railway station 17 | #include 18 | #include 19 | 20 | using namespace std; 21 | 22 | // Returns minimum number of platforms reqquired 23 | int findPlatform(int arr[], int dep[], int n) 24 | { 25 | // Sort arrival and departure arrays 26 | sort(arr, arr + n); 27 | sort(dep, dep + n); 28 | 29 | // plat_needed indicates number of platforms 30 | // needed at a time 31 | int plat_needed = 1, result = 1; 32 | int i = 1, j = 0; 33 | 34 | // Similar to merge in merge sort to process 35 | // all events in sorted order 36 | while (i < n && j < n) { 37 | // If next event in sorted order is arrival, 38 | // increment count of platforms needed 39 | if (arr[i] <= dep[j]) { 40 | plat_needed++; 41 | i++; 42 | } 43 | 44 | // Else decrement count of platforms needed 45 | else if (arr[i] > dep[j]) { 46 | plat_needed--; 47 | j++; 48 | } 49 | 50 | // Update result if needed 51 | if (plat_needed > result) 52 | result = plat_needed; 53 | } 54 | 55 | return result; 56 | } 57 | 58 | // Driver code 59 | int main() 60 | { 61 | int arr[] = { 900, 940, 950, 1100, 1500, 1800 }; 62 | int dep[] = { 910, 1200, 1120, 1130, 1900, 2000 }; 63 | int n = sizeof(arr) / sizeof(arr[0]); 64 | cout << "Minimum Number of Platforms Required = " 65 | << findPlatform(arr, dep, n); 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /Greedy/08_minimum_platform_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/minimum-platforms-1587115620/1 3 | 4 | sol: https://www.geeksforgeeks.org/minimum-number-platforms-required-railwaybus-station/ 5 | */ 6 | 7 | 8 | 9 | // ----------------------------------------------------------------------------------------------------------------------- // 10 | /* 11 | TC: O(N * logN) 12 | SC: O(1) 13 | */ 14 | 15 | // Program to find minimum number of platforms 16 | // required on a railway station 17 | #include 18 | #include 19 | 20 | using namespace std; 21 | 22 | // Returns minimum number of platforms reqquired 23 | int findPlatform(int arr[], int dep[], int n) 24 | { 25 | // Sort arrival and departure arrays 26 | sort(arr, arr + n); 27 | sort(dep, dep + n); 28 | 29 | // plat_needed indicates number of platforms 30 | // needed at a time 31 | int plat_needed = 1, result = 1; 32 | int i = 1, j = 0; 33 | 34 | // Similar to merge in merge sort to process 35 | // all events in sorted order 36 | while (i < n && j < n) { 37 | // If next event in sorted order is arrival, 38 | // increment count of platforms needed 39 | if (arr[i] <= dep[j]) { 40 | plat_needed++; 41 | i++; 42 | } 43 | 44 | // Else decrement count of platforms needed 45 | else if (arr[i] > dep[j]) { 46 | plat_needed--; 47 | j++; 48 | } 49 | 50 | // Update result if needed 51 | if (plat_needed > result) 52 | result = plat_needed; 53 | } 54 | 55 | return result; 56 | } 57 | 58 | // Driver code 59 | int main() 60 | { 61 | int arr[] = { 900, 940, 950, 1100, 1500, 1800 }; 62 | int dep[] = { 910, 1200, 1120, 1130, 1900, 2000 }; 63 | int n = sizeof(arr) / sizeof(arr[0]); 64 | cout << "Minimum Number of Platforms Required = " 65 | << findPlatform(arr, dep, n); 66 | return 0; 67 | } 68 | -------------------------------------------------------------------------------- /DP/17_painting_the_fence.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/painting-the-fence3727/1 3 | video: https://www.youtube.com/watch?v=ju8vrEAsa3Q 4 | 5 | variation of fibonacci 6 | 7 | */ 8 | 9 | // ----------------------------------------------------------------------------------------------------------------------- // 10 | 11 | // TC: O(N) 12 | int const mod = 1e9 + 7; 13 | int countWays(int n, int k) { 14 | if (n == 1) return k; 15 | 16 | // storing data for n==2 17 | // let assume last 2 are same as we can have only 2 same color in whole fence 18 | long long same = (k * 1) % mod; 19 | long long diff = (k * (k - 1)) % mod; 20 | long long total = (same + diff) % mod; 21 | 22 | for (int i = 3;i <= n;i++) { 23 | // take different of prev as they will have same color repeated at the end. 24 | same = diff % mod; 25 | // take total of prev as they have mixture but wont matter 26 | // eg. if prev: gg then add new => ggb, if prev: gb then add new gbg 27 | diff = (total * (k - 1)) % mod; 28 | 29 | total = (same + diff) % mod; 30 | } 31 | return total; 32 | } 33 | 34 | // ----------------------------------------------------------------------------------------------------------------------- // 35 | 36 | // tabulation 37 | long long const mod = 1e9 + 7; 38 | long long countWays(int n, int k) { 39 | long long dp[n + 1]; 40 | memset(dp, 0, sizeof(dp)); 41 | // base condition 42 | dp[1] = k; 43 | dp[2] = (k + ((k - 1) * k) % mod) % mod; 44 | 45 | for (int i = 3;i <= n;i++) { 46 | dp[i] = ((k - 1) * ((dp[i - 1] + dp[i - 2]) % mod)) % mod; 47 | } 48 | return dp[n]; 49 | } 50 | 51 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /GREEDY/07_maximum_trains_for_which_stoppage_can_be_provided.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/maximum-trains-stoppage-can-provided/ 3 | 4 | sort according to the departure time is crux of the problem. 5 | */ 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | // CPP to design platform for maximum stoppage 10 | #include 11 | using namespace std; 12 | 13 | // number of platforms and trains 14 | #define n 2 15 | #define m 5 16 | 17 | // function to calculate maximum trains stoppage 18 | int maxStop(int arr[][3]) 19 | { 20 | // declaring vector of pairs for platform 21 | vector > vect[n + 1]; 22 | 23 | // Entering values in vector of pairs 24 | // as per platform number 25 | // make departure time first element 26 | // of pair 27 | for (int i = 0; i < m; i++) 28 | vect[arr[i][2]].push_back( 29 | make_pair(arr[i][1], arr[i][0])); 30 | 31 | // sort trains for each platform as per 32 | // dept. time 33 | for (int i = 0; i <= n; i++) 34 | sort(vect[i].begin(), vect[i].end()); 35 | 36 | // perform activity selection approach 37 | int count = 0; 38 | for (int i = 0; i <= n; i++) { 39 | if (vect[i].size() == 0) 40 | continue; 41 | 42 | // first train for each platform will 43 | // also be selected 44 | int x = 0; 45 | count++; 46 | for (int j = 1; j < vect[i].size(); j++) { 47 | if (vect[i][j].second >= 48 | vect[i][x].first) { 49 | x = j; 50 | count++; 51 | } 52 | } 53 | } 54 | return count; 55 | } 56 | 57 | // driver function 58 | int main() 59 | { 60 | int arr[m][3] = { 1000, 1030, 1, 61 | 1010, 1020, 1, 62 | 1025, 1040, 1, 63 | 1130, 1145, 2, 64 | 1130, 1140, 2 65 | }; 66 | cout << "Maximum Stopped Trains = " 67 | << maxStop(arr); 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /Greedy/07_maximum_trains_for_which_stoppage_can_be_provided.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/maximum-trains-stoppage-can-provided/ 3 | 4 | sort according to the departure time is crux of the problem. 5 | */ 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | // CPP to design platform for maximum stoppage 10 | #include 11 | using namespace std; 12 | 13 | // number of platforms and trains 14 | #define n 2 15 | #define m 5 16 | 17 | // function to calculate maximum trains stoppage 18 | int maxStop(int arr[][3]) 19 | { 20 | // declaring vector of pairs for platform 21 | vector > vect[n + 1]; 22 | 23 | // Entering values in vector of pairs 24 | // as per platform number 25 | // make departure time first element 26 | // of pair 27 | for (int i = 0; i < m; i++) 28 | vect[arr[i][2]].push_back( 29 | make_pair(arr[i][1], arr[i][0])); 30 | 31 | // sort trains for each platform as per 32 | // dept. time 33 | for (int i = 0; i <= n; i++) 34 | sort(vect[i].begin(), vect[i].end()); 35 | 36 | // perform activity selection approach 37 | int count = 0; 38 | for (int i = 0; i <= n; i++) { 39 | if (vect[i].size() == 0) 40 | continue; 41 | 42 | // first train for each platform will 43 | // also be selected 44 | int x = 0; 45 | count++; 46 | for (int j = 1; j < vect[i].size(); j++) { 47 | if (vect[i][j].second >= 48 | vect[i][x].first) { 49 | x = j; 50 | count++; 51 | } 52 | } 53 | } 54 | return count; 55 | } 56 | 57 | // driver function 58 | int main() 59 | { 60 | int arr[m][3] = { 1000, 1030, 1, 61 | 1010, 1020, 1, 62 | 1025, 1040, 1, 63 | 1130, 1145, 2, 64 | 1130, 1140, 2 65 | }; 66 | cout << "Maximum Stopped Trains = " 67 | << maxStop(arr); 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /DP/54_count_balance_binary_tree.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/count-balanced-binary-trees-height-h/ 3 | 4 | all solution in link. 5 | 6 | logic: 7 | here as per 3 condition 8 | 9 | root 10 | / \ 11 | left sub tree right sub tree 12 | (h-2) (h-1) 13 | (h-1) (h-2) 14 | (h-1) (h-1) 15 | 16 | so 17 | count(h) = count(h-1) * count(h-2) + count(h-2) * count(h-1) + count(h-1) * count(h-1) 18 | = 2 * count(h-1) * count(h-2) + count(h-1) * count(h-1) 19 | = count(h-1) * (2*count(h - 2) + count(h - 1)) 20 | 21 | why multiply? 22 | bcoz for each sub tree with (h-2) it can be pair with all different (h-1) and vice-verca. 23 | 24 | why vice-verca ? 25 | bcoz it will be counted as unique if 26 | (h-2) height trees on left side and (h-1) on right side 27 | (h-1) height trees on left side and (h-2) on right side 28 | */ 29 | 30 | // ----------------------------------------------------------------------------------------------------------------------- // 31 | 32 | // C++ program to count number of balanced 33 | // binary trees of height h. 34 | #include 35 | #define mod 1000000007 36 | using namespace std; 37 | 38 | long long int countBT(int h) { 39 | 40 | long long int dp[h + 1]; 41 | //base cases 42 | dp[0] = dp[1] = 1; 43 | for (int i = 2; i <= h; i++) { 44 | dp[i] = (dp[i - 1] * ((2 * dp[i - 2]) % mod + dp[i - 1]) % mod) % mod; 45 | } 46 | return dp[h]; 47 | } 48 | // Driver program 49 | int main() 50 | { 51 | int h = 3; 52 | cout << "No. of balanced binary trees" 53 | " of height h is: " 54 | << countBT(h) << endl; 55 | } 56 | 57 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /DP/50_coin_game_winner_three_choice.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/coin-game-winner-every-player-three-choices/ 3 | */ 4 | 5 | // ----------------------------------------------------------------------------------------------------------------------- // 6 | 7 | // CPP program to find winner of game 8 | // if player can pick 1, x, y coins 9 | #include 10 | using namespace std; 11 | 12 | // To find winner of game 13 | bool findWinner(int x, int y, int n) 14 | { 15 | // To store results 16 | int dp[n + 1]; 17 | 18 | // Initial values 19 | dp[0] = false; 20 | dp[1] = true; 21 | 22 | // Computing other values. 23 | for (int i = 2; i <= n; i++) { 24 | 25 | // If A losses any of i-1 or i-x 26 | // or i-y game then he will 27 | // definitely win game i 28 | 29 | /* now in order to win, A has to loose previous one hence won by B and now check if 30 | i-1, i-x, i-y >=0 as well as A has loose the previous one so that A can win this one 31 | */ 32 | if (i - 1 >= 0 and !dp[i - 1]) 33 | dp[i] = true; 34 | else if (i - x >= 0 and !dp[i - x]) 35 | dp[i] = true; 36 | else if (i - y >= 0 and !dp[i - y]) 37 | dp[i] = true; 38 | 39 | // if A is not able to fulfill all the criteria then A loses game. 40 | else 41 | dp[i] = false; 42 | } 43 | 44 | // If dp[n] is true then A will 45 | // game otherwise he losses 46 | return dp[n]; 47 | } 48 | 49 | // Driver program to test findWinner(); 50 | int main() 51 | { 52 | int x = 3, y = 4, n = 5; 53 | if (findWinner(x, y, n)) 54 | cout << 'A'; 55 | else 56 | cout << 'B'; 57 | 58 | return 0; 59 | } 60 | 61 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /BACKTRACKING/04_remove_invalid_paranthesis.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://leetcode.com/problems/remove-invalid-parentheses/ 3 | 4 | video (this code gives TLE so tweaked code is below): https://youtu.be/Cbbf5qe5stw 5 | */ 6 | 7 | 8 | 9 | // ----------------------------------------------------------------------------------------------------------------------- // 10 | // this function will return how many 11 | int getMin(string s) { 12 | stack st; 13 | 14 | for (char c : s) { 15 | if (c == '(') st.push(c); 16 | // we are using else if as to ignore letters 17 | else if (c == ')') { 18 | if (st.size() == 0) st.push(c); 19 | else if (st.top() == ')') st.push(c); 20 | else if (st.top() == '(') st.pop(); 21 | } 22 | } 23 | return st.size(); 24 | } 25 | 26 | 27 | void backtracking(string s, int minRemAllowed, set& hs, unordered_set& vis) { 28 | // track record of every string visited at every stack call 29 | vis.insert(s); 30 | 31 | // if no more letters to remove 32 | if (minRemAllowed == 0) { 33 | // and our string is balanced then add to the set 34 | if (getMin(s) == 0) { 35 | hs.insert(s); 36 | } 37 | return; 38 | } 39 | 40 | for (int i = 0; i < s.size(); i++) { 41 | // get left ignoring the ith letter 42 | string left = s.substr(0, i); 43 | // get right ignoring the ith letter 44 | string right = s.substr(i + 1); 45 | 46 | // if currently formed string is already visited then ignore the stack call 47 | if (vis.find(left + right) != vis.end()) continue; 48 | backtracking(left + right, minRemAllowed - 1, hs, vis); 49 | } 50 | } 51 | 52 | 53 | vector removeInvalidParentheses(string s) { 54 | // vs.clear(); 55 | 56 | int minRemoval = getMin(s); 57 | set hs; 58 | unordered_set vis; 59 | 60 | backtracking(s, minRemoval, hs, vis); 61 | 62 | // finally convert set to vector 63 | vector vs(hs.begin(), hs.end()); 64 | 65 | return vs; 66 | } -------------------------------------------------------------------------------- /GREEDY/33_find_smallest_no_given_total_no_of_digits_and_sum_of_digits.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/smallest-number5829/1 3 | 4 | sol: https://www.geeksforgeeks.org/find-smallest-number-with-given-number-of-digits-and-digit-sum/ 5 | */ 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | // C++ program to find the smallest number that can be 10 | // formed from given sum of digits and number of digits. 11 | #include 12 | using namespace std; 13 | 14 | // Prints the smallest possible number with digit sum 's' 15 | // and 'm' number of digits. 16 | void findSmallest(int m, int s) 17 | { 18 | // If sum of digits is 0, then a number is possible 19 | // only if number of digits is 1. 20 | if (s == 0) 21 | { 22 | (m == 1) ? cout << "Smallest number is " << 0 23 | : cout << "Not possible"; 24 | return; 25 | } 26 | 27 | // Sum greater than the maximum possible sum. 28 | if (s > 9 * m) 29 | { 30 | cout << "Not possible"; 31 | return; 32 | } 33 | 34 | // Create an array to store digits of result 35 | int res[m]; 36 | 37 | // deduct sum by one to account for cases later 38 | // (There must be 1 left for the most significant 39 | // digit) 40 | s -= 1; 41 | 42 | // Fill last m-1 digits (from right to left) 43 | for (int i = m - 1; i > 0; i--) 44 | { 45 | // If sum is still greater than 9, 46 | // digit must be 9. 47 | if (s > 9) 48 | { 49 | res[i] = 9; 50 | s -= 9; 51 | } 52 | else 53 | { 54 | res[i] = s; 55 | s = 0; 56 | } 57 | } 58 | 59 | // Whatever is left should be the most significant 60 | // digit. 61 | res[0] += s + 1; // The initially subtracted 1 is 62 | // incorporated here. 63 | 64 | cout << "Smallest number is "; 65 | for (int i = 0; i < m; i++) 66 | cout << res[i]; 67 | } 68 | 69 | // Driver code 70 | int main() 71 | { 72 | int s = 9, m = 2; 73 | findSmallest(m, s); 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /Greedy/33_find_smallest_no_given_total_no_of_digits_and_sum_of_digits.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/smallest-number5829/1 3 | 4 | sol: https://www.geeksforgeeks.org/find-smallest-number-with-given-number-of-digits-and-digit-sum/ 5 | */ 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | // C++ program to find the smallest number that can be 10 | // formed from given sum of digits and number of digits. 11 | #include 12 | using namespace std; 13 | 14 | // Prints the smallest possible number with digit sum 's' 15 | // and 'm' number of digits. 16 | void findSmallest(int m, int s) 17 | { 18 | // If sum of digits is 0, then a number is possible 19 | // only if number of digits is 1. 20 | if (s == 0) 21 | { 22 | (m == 1) ? cout << "Smallest number is " << 0 23 | : cout << "Not possible"; 24 | return; 25 | } 26 | 27 | // Sum greater than the maximum possible sum. 28 | if (s > 9 * m) 29 | { 30 | cout << "Not possible"; 31 | return; 32 | } 33 | 34 | // Create an array to store digits of result 35 | int res[m]; 36 | 37 | // deduct sum by one to account for cases later 38 | // (There must be 1 left for the most significant 39 | // digit) 40 | s -= 1; 41 | 42 | // Fill last m-1 digits (from right to left) 43 | for (int i = m - 1; i > 0; i--) 44 | { 45 | // If sum is still greater than 9, 46 | // digit must be 9. 47 | if (s > 9) 48 | { 49 | res[i] = 9; 50 | s -= 9; 51 | } 52 | else 53 | { 54 | res[i] = s; 55 | s = 0; 56 | } 57 | } 58 | 59 | // Whatever is left should be the most significant 60 | // digit. 61 | res[0] += s + 1; // The initially subtracted 1 is 62 | // incorporated here. 63 | 64 | cout << "Smallest number is "; 65 | for (int i = 0; i < m; i++) 66 | cout << res[i]; 67 | } 68 | 69 | // Driver code 70 | int main() 71 | { 72 | int s = 9, m = 2; 73 | findSmallest(m, s); 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /GREEDY/21_shortest_job_first_SJF.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link (can also refer another code here): [for non-preemptive] 3 | https://www.geeksforgeeks.org/program-for-shortest-job-first-or-sjf-cpu-scheduling-set-1-non-preemptive/ 4 | 5 | link: [for preemptive] 6 | https://www.geeksforgeeks.org/program-for-shortest-job-first-sjf-scheduling-set-2-preemptive/ 7 | 8 | video: https://youtu.be/9PDUOx4MtKo 9 | */ 10 | 11 | 12 | // ----------------------------------------------------------------------------------------------------------------------- // 13 | #include 14 | using namespace std; 15 | 16 | // priority while sorting: arrival time, burst time, id 17 | bool comp(vector a, vector b) { 18 | if (a[1] == b[1]) { 19 | if (a[2] == b[2]) { 20 | return a[0] < b[0]; 21 | } 22 | else { 23 | return a[2] < b[2]; 24 | } 25 | } 26 | return a[1] < b[1]; 27 | } 28 | 29 | int main() { 30 | int n; 31 | cin >> n; 32 | 33 | vector> v(n); 34 | 35 | // insert the data: id, arrival time, burst time 36 | for (int i = 0; i < n; i++) { 37 | for (int j = 0; j < 3; j++) { 38 | int x; 39 | cin >> x; 40 | v[i].push_back(x); 41 | } 42 | } 43 | 44 | vector ans; 45 | 46 | sort(v.begin(), v.end(), comp); 47 | 48 | priority_queue, vector>, greater>> pq; 49 | 50 | // insert in order like: burst time, arrival time, id => as we want to sort them in order of burst time 51 | pq.push({ v[0][2], v[0][1], v[0][0] }); 52 | 53 | int i = 1, current_time = 0; 54 | 55 | while (!pq.empty()) { // TC: O(N) 56 | int burst_time = pq.top()[0]; 57 | int id = pq.top()[2]; 58 | pq.pop(); 59 | 60 | ans.push_back(id); // TC: O(logN) 61 | current_time += burst_time; 62 | 63 | while (true) { 64 | if (i < n && v[i][1] <= current_time) { 65 | pq.push({ v[i][2], v[i][1], v[i][0] }); 66 | i++; 67 | } 68 | else break; 69 | } 70 | } 71 | 72 | for (int i = 0; i < ans.size(); i++) { 73 | cout << ans[i] << " "; 74 | } 75 | } -------------------------------------------------------------------------------- /Greedy/21_shortest_job_first_SJF.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link (can also refer another code here): [for non-preemptive] 3 | https://www.geeksforgeeks.org/program-for-shortest-job-first-or-sjf-cpu-scheduling-set-1-non-preemptive/ 4 | 5 | link: [for preemptive] 6 | https://www.geeksforgeeks.org/program-for-shortest-job-first-sjf-scheduling-set-2-preemptive/ 7 | 8 | video: https://youtu.be/9PDUOx4MtKo 9 | */ 10 | 11 | 12 | // ----------------------------------------------------------------------------------------------------------------------- // 13 | #include 14 | using namespace std; 15 | 16 | // priority while sorting: arrival time, burst time, id 17 | bool comp(vector a, vector b) { 18 | if (a[1] == b[1]) { 19 | if (a[2] == b[2]) { 20 | return a[0] < b[0]; 21 | } 22 | else { 23 | return a[2] < b[2]; 24 | } 25 | } 26 | return a[1] < b[1]; 27 | } 28 | 29 | int main() { 30 | int n; 31 | cin >> n; 32 | 33 | vector> v(n); 34 | 35 | // insert the data: id, arrival time, burst time 36 | for (int i = 0; i < n; i++) { 37 | for (int j = 0; j < 3; j++) { 38 | int x; 39 | cin >> x; 40 | v[i].push_back(x); 41 | } 42 | } 43 | 44 | vector ans; 45 | 46 | sort(v.begin(), v.end(), comp); 47 | 48 | priority_queue, vector>, greater>> pq; 49 | 50 | // insert in order like: burst time, arrival time, id => as we want to sort them in order of burst time 51 | pq.push({ v[0][2], v[0][1], v[0][0] }); 52 | 53 | int i = 1, current_time = 0; 54 | 55 | while (!pq.empty()) { // TC: O(N) 56 | int burst_time = pq.top()[0]; 57 | int id = pq.top()[2]; 58 | pq.pop(); 59 | 60 | ans.push_back(id); // TC: O(logN) 61 | current_time += burst_time; 62 | 63 | while (true) { 64 | if (i < n && v[i][1] <= current_time) { 65 | pq.push({ v[i][2], v[i][1], v[i][0] }); 66 | i++; 67 | } 68 | else break; 69 | } 70 | } 71 | 72 | for (int i = 0; i < ans.size(); i++) { 73 | cout << ans[i] << " "; 74 | } 75 | } -------------------------------------------------------------------------------- /GREEDY/15_maximum_product_subset_of_an_array.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/maximum-product-subset-array/ 3 | 4 | this counting method is more efficient 5 | 6 | other method would be to sort 7 | */ 8 | 9 | 10 | // ----------------------------------------------------------------------------------------------------------------------- // 11 | /* 12 | Time Complexity: O(n) 13 | Auxiliary Space: O(1) 14 | */ 15 | // CPP program to find maximum product of 16 | // a subset. 17 | #include 18 | using namespace std; 19 | 20 | int maxProductSubset(int a[], int n) 21 | { 22 | if (n == 1) 23 | return a[0]; 24 | 25 | // Find count of negative numbers, count 26 | // of zeros, negative number 27 | // with least absolute value 28 | // and product of non-zero numbers 29 | int max_neg = INT_MIN; 30 | int count_neg = 0, count_zero = 0; 31 | int prod = 1; 32 | for (int i = 0; i < n; i++) { 33 | 34 | // If number is 0, we don't 35 | // multiply it with product. 36 | if (a[i] == 0) { 37 | count_zero++; 38 | continue; 39 | } 40 | 41 | // Count negatives and keep 42 | // track of negative number 43 | // with least absolute value 44 | if (a[i] < 0) { 45 | count_neg++; 46 | max_neg = max(max_neg, a[i]); 47 | } 48 | 49 | prod = prod * a[i]; 50 | } 51 | 52 | // If there are all zeros 53 | if (count_zero == n) 54 | return 0; 55 | 56 | // If there are odd number of 57 | // negative numbers 58 | if (count_neg & 1) { 59 | 60 | // Exceptional case: There is only 61 | // negative and all other are zeros 62 | if (count_neg == 1 && 63 | count_zero > 0 && 64 | count_zero + count_neg == n) 65 | return 0; 66 | 67 | // Otherwise result is product of 68 | // all non-zeros divided by 69 | //negative number with 70 | // least absolute value 71 | prod = prod / max_neg; 72 | } 73 | 74 | return prod; 75 | } 76 | 77 | // Driver Code 78 | int main() 79 | { 80 | int a[] = { -1, -1, -2, 4, 3 }; 81 | int n = sizeof(a) / sizeof(a[0]); 82 | cout << maxProductSubset(a, n); 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /Greedy/15_maximum_product_subset_of_an_array.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/maximum-product-subset-array/ 3 | 4 | this counting method is more efficient 5 | 6 | other method would be to sort 7 | */ 8 | 9 | 10 | // ----------------------------------------------------------------------------------------------------------------------- // 11 | /* 12 | Time Complexity: O(n) 13 | Auxiliary Space: O(1) 14 | */ 15 | // CPP program to find maximum product of 16 | // a subset. 17 | #include 18 | using namespace std; 19 | 20 | int maxProductSubset(int a[], int n) 21 | { 22 | if (n == 1) 23 | return a[0]; 24 | 25 | // Find count of negative numbers, count 26 | // of zeros, negative number 27 | // with least absolute value 28 | // and product of non-zero numbers 29 | int max_neg = INT_MIN; 30 | int count_neg = 0, count_zero = 0; 31 | int prod = 1; 32 | for (int i = 0; i < n; i++) { 33 | 34 | // If number is 0, we don't 35 | // multiply it with product. 36 | if (a[i] == 0) { 37 | count_zero++; 38 | continue; 39 | } 40 | 41 | // Count negatives and keep 42 | // track of negative number 43 | // with least absolute value 44 | if (a[i] < 0) { 45 | count_neg++; 46 | max_neg = max(max_neg, a[i]); 47 | } 48 | 49 | prod = prod * a[i]; 50 | } 51 | 52 | // If there are all zeros 53 | if (count_zero == n) 54 | return 0; 55 | 56 | // If there are odd number of 57 | // negative numbers 58 | if (count_neg & 1) { 59 | 60 | // Exceptional case: There is only 61 | // negative and all other are zeros 62 | if (count_neg == 1 && 63 | count_zero > 0 && 64 | count_zero + count_neg == n) 65 | return 0; 66 | 67 | // Otherwise result is product of 68 | // all non-zeros divided by 69 | //negative number with 70 | // least absolute value 71 | prod = prod / max_neg; 72 | } 73 | 74 | return prod; 75 | } 76 | 77 | // Driver Code 78 | int main() 79 | { 80 | int a[] = { -1, -1, -2, 4, 3 }; 81 | int n = sizeof(a) / sizeof(a[0]); 82 | cout << maxProductSubset(a, n); 83 | return 0; 84 | } 85 | -------------------------------------------------------------------------------- /BACKTRACKING/05_sudoku_solver.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/solve-the-sudoku-1587115621/1 3 | 4 | video: https://youtu.be/FWAIf_EVUKE 5 | 6 | (for more ref. or codes): https://www.geeksforgeeks.org/sudoku-backtracking-7/ 7 | */ 8 | 9 | 10 | 11 | 12 | // ----------------------------------------------------------------------------------------------------------------------- // 13 | /* 14 | TC: O(9^(n*n)) as every N*N place in box has 9 possibilities 15 | */ 16 | bool isValid(int row, int col, int curr, int grid[N][N]) { 17 | for (int i = 0; i < 9; i++) { 18 | // checking in row 19 | if (grid[i][col] == curr) return false; 20 | 21 | // checking in col 22 | if (grid[row][i] == curr) return false; 23 | 24 | // checking in current block of sudoku 25 | if (grid[3 * (row / 3) + i / 3][3 * (col / 3) + i % 3] == curr) return false; 26 | 27 | } 28 | return true; 29 | } 30 | 31 | bool SolveSudoku(int grid[N][N]) 32 | { 33 | // for every position 34 | for (int i = 0; i < N; i++) { 35 | for (int j = 0; j < N; j++) { 36 | // if it is to fill then... 37 | if (grid[i][j] == 0) { 38 | // for every possible no. 39 | for (int curr = 1; curr <= 9; curr++) { 40 | // if current no. is valid to fill then we will go for the recursion (possibilities) 41 | if (isValid(i, j, curr, grid)) { 42 | // fill current pos 43 | grid[i][j] = curr; 44 | // recur for next empty pos 45 | if (SolveSudoku(grid)) return true; 46 | // if valid filled position didn't return true 47 | // because other no. might not accomodate validly 48 | // again empty the current pos 49 | else grid[i][j] = 0; 50 | } 51 | } 52 | // if not even single no. accomodated return false 53 | return false; 54 | } 55 | } 56 | } 57 | // if sudoku size is 0x0 58 | return true; 59 | } 60 | 61 | //Function to print grids of the Sudoku. 62 | void printGrid(int grid[N][N]) 63 | { 64 | // Your code here 65 | for (int i = 0; i < N; i++) { 66 | for (int j = 0; j < N; j++) { 67 | cout << grid[i][j] << " "; 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /DP/49_count_derangements.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/count-derangements-permutation-such-that-no-element-appears-in-its-original-position/ 3 | 4 | video: https://www.youtube.com/watch?v=WMmx6kDxaDQ 5 | 6 | source code is there in link. 7 | to understand recursion relation watch video. 8 | */ 9 | 10 | // ----------------------------------------------------------------------------------------------------------------------- // 11 | 12 | // dp sol. 13 | // TC: O(N), SC: O(N) 14 | #include 15 | using namespace std; 16 | 17 | int countDer(int n) 18 | { 19 | // Create an array to store 20 | // counts for subproblems 21 | int der[n + 1] = { 0 }; 22 | 23 | // Base cases 24 | der[1] = 0; 25 | der[2] = 1; 26 | 27 | // Fill der[0..n] in bottom up manner 28 | // using above recursive formula 29 | for (int i = 3; i <= n; ++i) 30 | der[i] = (i - 1) * (der[i - 1] + 31 | der[i - 2]); 32 | 33 | // Return result for n 34 | return der[n]; 35 | } 36 | int main() 37 | { 38 | int n = 4; 39 | cout << "Count of Derangements is " 40 | << countDer(n); 41 | return 0; 42 | } 43 | 44 | // ----------------------------------------------------------------------------------------------------------------------- // 45 | 46 | // TC: O(N), SC: O(1) 47 | #include 48 | using namespace std; 49 | 50 | int countDer(int n) 51 | { 52 | 53 | // base case 54 | if (n == 1 or n == 2) { 55 | return n - 1; 56 | } 57 | 58 | // Variable for just storing 59 | // previous values 60 | int a = 0; 61 | int b = 1; 62 | 63 | // using above recursive formula 64 | for (int i = 3; i <= n; ++i) { 65 | int cur = (i - 1) * (a + b); 66 | a = b; 67 | b = cur; 68 | } 69 | 70 | // Return result for n 71 | return b; 72 | } 73 | 74 | // Driver Code 75 | int main() 76 | { 77 | cout << "Count of Dearrangements is " << countDer(4); 78 | return 0; 79 | } 80 | 81 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /GREEDY/35_find_maximum_sum_possible_equal_sum_of_three_stacks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/find-maximum-sum-possible-equal-sum-three-stacks/ 3 | */ 4 | 5 | 6 | // ----------------------------------------------------------------------------------------------------------------------- // 7 | /* 8 | Time Complexity : O(n1 + n2 + n3) where n1, n2 and n3 are sizes of three stacks. 9 | */ 10 | 11 | // C++ program to calculate maximum sum with equal 12 | // stack sum. 13 | #include 14 | using namespace std; 15 | 16 | // Returns maximum possible equal sum of three stacks 17 | // with removal of top elements allowed 18 | int maxSum(int stack1[], int stack2[], int stack3[], int n1, 19 | int n2, int n3) 20 | { 21 | int sum1 = 0, sum2 = 0, sum3 = 0; 22 | 23 | // Finding the initial sum of stack1. 24 | for (int i = 0; i < n1; i++) 25 | sum1 += stack1[i]; 26 | 27 | // Finding the initial sum of stack2. 28 | for (int i = 0; i < n2; i++) 29 | sum2 += stack2[i]; 30 | 31 | // Finding the initial sum of stack3. 32 | for (int i = 0; i < n3; i++) 33 | sum3 += stack3[i]; 34 | 35 | // As given in question, first element is top 36 | // of stack.. 37 | int top1 = 0, top2 = 0, top3 = 0; 38 | while (1) { 39 | // If any stack is empty 40 | if (top1 == n1 || top2 == n2 || top3 == n3) 41 | return 0; 42 | 43 | // If sum of all three stack are equal. 44 | if (sum1 == sum2 && sum2 == sum3) 45 | return sum1; 46 | 47 | // Finding the stack with maximum sum and 48 | // removing its top element. 49 | if (sum1 >= sum2 && sum1 >= sum3) 50 | sum1 -= stack1[top1++]; 51 | else if (sum2 >= sum1 && sum2 >= sum3) 52 | sum2 -= stack2[top2++]; 53 | else if (sum3 >= sum2 && sum3 >= sum1) 54 | sum3 -= stack3[top3++]; 55 | } 56 | } 57 | 58 | // Driven Program 59 | int main() 60 | { 61 | int stack1[] = { 3, 2, 1, 1, 1 }; 62 | int stack2[] = { 4, 3, 2 }; 63 | int stack3[] = { 1, 1, 4, 1 }; 64 | 65 | int n1 = sizeof(stack1) / sizeof(stack1[0]); 66 | int n2 = sizeof(stack2) / sizeof(stack2[0]); 67 | int n3 = sizeof(stack3) / sizeof(stack3[0]); 68 | 69 | cout << maxSum(stack1, stack2, stack3, n1, n2, n3) 70 | << endl; 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /Greedy/35_find_maximum_sum_possible_equal_sum_of_three_stacks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/find-maximum-sum-possible-equal-sum-three-stacks/ 3 | */ 4 | 5 | 6 | // ----------------------------------------------------------------------------------------------------------------------- // 7 | /* 8 | Time Complexity : O(n1 + n2 + n3) where n1, n2 and n3 are sizes of three stacks. 9 | */ 10 | 11 | // C++ program to calculate maximum sum with equal 12 | // stack sum. 13 | #include 14 | using namespace std; 15 | 16 | // Returns maximum possible equal sum of three stacks 17 | // with removal of top elements allowed 18 | int maxSum(int stack1[], int stack2[], int stack3[], int n1, 19 | int n2, int n3) 20 | { 21 | int sum1 = 0, sum2 = 0, sum3 = 0; 22 | 23 | // Finding the initial sum of stack1. 24 | for (int i = 0; i < n1; i++) 25 | sum1 += stack1[i]; 26 | 27 | // Finding the initial sum of stack2. 28 | for (int i = 0; i < n2; i++) 29 | sum2 += stack2[i]; 30 | 31 | // Finding the initial sum of stack3. 32 | for (int i = 0; i < n3; i++) 33 | sum3 += stack3[i]; 34 | 35 | // As given in question, first element is top 36 | // of stack.. 37 | int top1 = 0, top2 = 0, top3 = 0; 38 | while (1) { 39 | // If any stack is empty 40 | if (top1 == n1 || top2 == n2 || top3 == n3) 41 | return 0; 42 | 43 | // If sum of all three stack are equal. 44 | if (sum1 == sum2 && sum2 == sum3) 45 | return sum1; 46 | 47 | // Finding the stack with maximum sum and 48 | // removing its top element. 49 | if (sum1 >= sum2 && sum1 >= sum3) 50 | sum1 -= stack1[top1++]; 51 | else if (sum2 >= sum1 && sum2 >= sum3) 52 | sum2 -= stack2[top2++]; 53 | else if (sum3 >= sum2 && sum3 >= sum1) 54 | sum3 -= stack3[top3++]; 55 | } 56 | } 57 | 58 | // Driven Program 59 | int main() 60 | { 61 | int stack1[] = { 3, 2, 1, 1, 1 }; 62 | int stack2[] = { 4, 3, 2 }; 63 | int stack3[] = { 1, 1, 4, 1 }; 64 | 65 | int n1 = sizeof(stack1) / sizeof(stack1[0]); 66 | int n2 = sizeof(stack2) / sizeof(stack2[0]); 67 | int n3 = sizeof(stack3) / sizeof(stack3[0]); 68 | 69 | cout << maxSum(stack1, stack2, stack3, n1, n2, n3) 70 | << endl; 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /DP/35_kadanes_algo_OR_largest_sum_contigous_array.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/kadanes-algorithm-1587115620/1 3 | 4 | variation of LIS but here not subsequence but subarray in contigous manner. 5 | also variation of 1/0 knapsack. 6 | */ 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | 10 | // arr: input array 11 | // n: size of array 12 | //Function to find the sum of contiguous subarray with maximum sum. 13 | 14 | // TC: O(N) 15 | int maxSubarraySum(int arr[], int n) { 16 | int dp[n]; 17 | 18 | dp[0] = max(0, arr[0]); 19 | int omax = dp[0]; 20 | for (int i = 1;i < n;i++) { 21 | // choosing either to keep the subarray continue or break and initialize with current ele. 22 | dp[i] = max(dp[i - 1] + arr[i], arr[i]); 23 | // also keeping track of highest sum achieved during the journey. 24 | omax = max(dp[i], omax); 25 | } 26 | return omax; 27 | } 28 | 29 | // ----------------------------------------------------------------------------------------------------------------------- // 30 | 31 | // simple algo.. 32 | // TC: O(N) 33 | class Solution { 34 | public: 35 | //Function to find the sum of contiguous subarray with maximum sum. 36 | int maxSubarraySum(int a[], int n) { 37 | 38 | long long maxh = 0, maxf = INT_MIN; 39 | 40 | //Iterating over the array. 41 | for (int i = 0;i < n;i++) 42 | { 43 | //Updating max sum till current index. 44 | maxh += a[i]; 45 | //Storing max sum so far by choosing maximum between max 46 | //sum so far and max till current index. 47 | maxf = max(maxh, maxf); 48 | 49 | //If max sum at current index is negative, we do not need to add 50 | //it to result so we update it to zero. 51 | if (maxh < 0) 52 | maxh = 0; 53 | 54 | } 55 | //returning the result. 56 | return maxf; 57 | 58 | } 59 | }; 60 | 61 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /BACKTRACKING/08_subset_sum_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/subset-sum-problem2014/1 3 | */ 4 | 5 | 6 | 7 | // ----------------------------------------------------------------------------------------------------------------------- // 8 | /* 9 | TC: O(N) 10 | */ 11 | bool solve(int idx, int sum, vector& ans, int arr[], int N) { 12 | // if sum is already less than 0 or index is out of bound 13 | if (sum < 0 || idx >= N) return false; 14 | 15 | // if we get perfect sum ==0 means we got the combination 16 | if (sum == 0) return true; 17 | 18 | // if try to push current elem. 19 | ans.push_back(arr[idx]); 20 | 21 | // if current element worked 22 | if (solve(idx + 1, sum - arr[idx], ans, arr, N)) return true; 23 | 24 | // if curr ele didn't work pop it 25 | ans.pop_back(); 26 | 27 | 28 | // basically ignoring the current ele and going for other combination 29 | return solve(idx + 1, sum, ans, arr, N); 30 | } 31 | 32 | int equalPartition(int N, int arr[]) 33 | { 34 | int sum = 0; 35 | for (int i = 0; i < N; i++) { 36 | sum += arr[i]; 37 | } 38 | 39 | // just in case to get partition 40 | vector ans; 41 | 42 | // if sum is odd it is not possible to separate no.(s) 43 | // eg. sum = 11, now there exist no two such group whose individual total would be same and 44 | // overall total will be 11 45 | return sum % 2 == 0 && solve(0, sum / 2, ans, arr, N); 46 | } 47 | 48 | 49 | 50 | 51 | 52 | // ----------------------------------------------------------------------------------------------------------------------- // 53 | /* 54 | alternate solution 55 | */ 56 | bool solve(int arr[], int curr, int sum, int idx, int N) { 57 | if (curr > sum || idx >= N) return false; 58 | if (curr == sum) return true; 59 | 60 | // taking the current element 61 | if (solve(arr, curr + arr[idx], sum, idx + 1, N)) return true; 62 | 63 | // ignoring the current element 64 | if (solve(arr, curr, sum, idx + 1, N)) return true; 65 | 66 | return false; 67 | } 68 | 69 | int equalPartition(int N, int arr[]) 70 | { 71 | int sum = 0; 72 | for (int i = 0; i < N; i++) { 73 | sum += arr[i]; 74 | } 75 | 76 | return sum % 2 == 0 && solve(arr, 0, sum / 2, 0, N); 77 | } -------------------------------------------------------------------------------- /GREEDY/06_find_minimum_no_of_coins.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/choose-and-swap0531/1 3 | 4 | sol: https://www.geeksforgeeks.org/swap-all-occurrences-of-two-characters-to-get-lexicographically-smallest-string/ 5 | */ 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | // C++ implementation of the approach 10 | #include 11 | using namespace std; 12 | 13 | #define MAX 26 14 | 15 | // Function to return the lexicographically 16 | // smallest string after swapping all the 17 | // occurrences of any two characters 18 | string smallestStr(string str, int n) 19 | { 20 | int i, j; 21 | // To store the first index of 22 | // every character of str 23 | int chk[MAX]; 24 | for (i = 0; i < MAX; i++) 25 | chk[i] = -1; 26 | 27 | // Store the first occurring 28 | // index every character 29 | for (i = 0; i < n; i++) { 30 | 31 | // If current character is appearing 32 | // for the first time in str 33 | if (chk[str[i] - 'a'] == -1) 34 | chk[str[i] - 'a'] = i; 35 | } 36 | 37 | // Starting from the leftmost character 38 | for (i = 0; i < n; i++) { 39 | 40 | bool flag = false; 41 | 42 | // For every character smaller than str[i] 43 | for (j = 0; j < str[i] - 'a'; j++) { 44 | 45 | // If there is a character in str which is 46 | // smaller than str[i] and appears after it 47 | if (chk[j] > chk[str[i] - 'a']) { 48 | flag = true; 49 | break; 50 | } 51 | } 52 | 53 | // If the required character pair is found 54 | if (flag) 55 | break; 56 | } 57 | 58 | // If swapping is possible 59 | if (i < n) { 60 | 61 | // Characters to be swapped 62 | char ch1 = str[i]; 63 | char ch2 = char(j + 'a'); 64 | 65 | // For every character 66 | for (i = 0; i < n; i++) { 67 | 68 | // Replace every ch1 with ch2 69 | // and every ch2 with ch1 70 | if (str[i] == ch1) 71 | str[i] = ch2; 72 | 73 | else if (str[i] == ch2) 74 | str[i] = ch1; 75 | } 76 | } 77 | 78 | return str; 79 | } 80 | 81 | // Driver code 82 | int main() 83 | { 84 | string str = "ccad"; 85 | int n = str.length(); 86 | 87 | cout << smallestStr(str, n); 88 | 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /Greedy/06_find_minimum_no_of_coins.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/choose-and-swap0531/1 3 | 4 | sol: https://www.geeksforgeeks.org/swap-all-occurrences-of-two-characters-to-get-lexicographically-smallest-string/ 5 | */ 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | // C++ implementation of the approach 10 | #include 11 | using namespace std; 12 | 13 | #define MAX 26 14 | 15 | // Function to return the lexicographically 16 | // smallest string after swapping all the 17 | // occurrences of any two characters 18 | string smallestStr(string str, int n) 19 | { 20 | int i, j; 21 | // To store the first index of 22 | // every character of str 23 | int chk[MAX]; 24 | for (i = 0; i < MAX; i++) 25 | chk[i] = -1; 26 | 27 | // Store the first occurring 28 | // index every character 29 | for (i = 0; i < n; i++) { 30 | 31 | // If current character is appearing 32 | // for the first time in str 33 | if (chk[str[i] - 'a'] == -1) 34 | chk[str[i] - 'a'] = i; 35 | } 36 | 37 | // Starting from the leftmost character 38 | for (i = 0; i < n; i++) { 39 | 40 | bool flag = false; 41 | 42 | // For every character smaller than str[i] 43 | for (j = 0; j < str[i] - 'a'; j++) { 44 | 45 | // If there is a character in str which is 46 | // smaller than str[i] and appears after it 47 | if (chk[j] > chk[str[i] - 'a']) { 48 | flag = true; 49 | break; 50 | } 51 | } 52 | 53 | // If the required character pair is found 54 | if (flag) 55 | break; 56 | } 57 | 58 | // If swapping is possible 59 | if (i < n) { 60 | 61 | // Characters to be swapped 62 | char ch1 = str[i]; 63 | char ch2 = char(j + 'a'); 64 | 65 | // For every character 66 | for (i = 0; i < n; i++) { 67 | 68 | // Replace every ch1 with ch2 69 | // and every ch2 with ch1 70 | if (str[i] == ch1) 71 | str[i] = ch2; 72 | 73 | else if (str[i] == ch2) 74 | str[i] = ch1; 75 | } 76 | } 77 | 78 | return str; 79 | } 80 | 81 | // Driver code 82 | int main() 83 | { 84 | string str = "ccad"; 85 | int n = str.length(); 86 | 87 | cout << smallestStr(str, n); 88 | 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /DP/34_count_no_of_ways_to_reach_given_score.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/reach-a-given-score-1587115621/1 3 | 4 | variation of unbound knapsack. 5 | 6 | how it is different than rop cutting problem? 7 | ans : In rope cutting we were aiming to return max length while here we want distict pairs 8 | 9 | */ 10 | 11 | // ----------------------------------------------------------------------------------------------------------------------- // 12 | 13 | // correct sol. 14 | // here total ways will be return (distinct). 15 | long long int count(long long int n) 16 | { 17 | long long int table[n + 1], i; 18 | memset(table, 0, sizeof(table)); 19 | table[0] = 1; // If 0 sum is required number of ways is 1. 20 | for (i = 3;i <= n;i++) 21 | table[i] += table[i - 3]; // For every points (3,5,10) you need to add the number of ways to reach that sum 22 | for (i = 5;i <= n;i++) // before adding these points. 23 | table[i] += table[i - 5]; 24 | for (i = 10;i <= n;i++) 25 | table[i] += table[i - 10]; 26 | return table[n]; 27 | } 28 | 29 | // ----------------------------------------------------------------------------------------------------------------------- // 30 | 31 | // this won't work as here it will not return distict pairs.. 32 | long long int count(long long int n) 33 | { 34 | long long int table[n + 1], i; 35 | memset(table, 0, sizeof(table)); 36 | table[0] = 1; // If 0 sum is required number of ways is 1(by not picking any path, direct winner). 37 | 38 | // Your code here 39 | // here it is given fix that score possible are 3,5,10. 40 | for (i = 1;i < n + 1;i++) { 41 | for (int j = 1;j < n + 1;j++) { 42 | if (j >= 3) { 43 | table[i] += table[j - 3]; 44 | } 45 | if (j >= 5) { 46 | table[i] = table[j - 5]; 47 | } 48 | if (j >= 10) { 49 | table[i] += table[j - 10]; 50 | } 51 | } 52 | } 53 | 54 | return table[n]; 55 | } 56 | 57 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /GREEDY/05_fractional_knapsack_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/fractional-knapsack-1587115620/1 3 | 4 | sol: https://www.geeksforgeeks.org/fractional-knapsack-problem/ 5 | */ 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | /* 10 | TC: O(N) 11 | */ 12 | // C/C++ program to solve fractional Knapsack Problem 13 | #include 14 | 15 | using namespace std; 16 | 17 | // Structure for an item which stores weight and 18 | // corresponding value of Item 19 | struct Item { 20 | int value, weight; 21 | 22 | // Constructor 23 | Item(int value, int weight) 24 | { 25 | this->value = value; 26 | this->weight = weight; 27 | } 28 | }; 29 | 30 | // Comparison function to sort Item according to val/weight 31 | // ratio 32 | bool cmp(struct Item a, struct Item b) 33 | { 34 | double r1 = (double)a.value / (double)a.weight; 35 | double r2 = (double)b.value / (double)b.weight; 36 | return r1 > r2; 37 | } 38 | 39 | // Main greedy function to solve problem 40 | double fractionalKnapsack(int W, struct Item arr[], int n) 41 | { 42 | // sorting Item on basis of ratio 43 | sort(arr, arr + n, cmp); 44 | 45 | int curWeight = 0; // Current weight in knapsack 46 | double finalvalue = 0.0; // Result (value in Knapsack) 47 | 48 | // Looping through all Items 49 | for (int i = 0; i < n; i++) { 50 | // If adding Item won't overflow, add it completely 51 | if (curWeight + arr[i].weight <= W) { 52 | curWeight += arr[i].weight; 53 | finalvalue += arr[i].value; 54 | } 55 | 56 | // If we can't add current Item, add fractional part 57 | // of it 58 | else { 59 | int remain = W - curWeight; 60 | finalvalue += arr[i].value 61 | * ((double)remain 62 | / (double)arr[i].weight); 63 | break; 64 | } 65 | } 66 | 67 | // Returning final value 68 | return finalvalue; 69 | } 70 | 71 | // Driver code 72 | int main() 73 | { 74 | int W = 50; // Weight of knapsack 75 | Item arr[] = { { 60, 10 }, { 100, 20 }, { 120, 30 } }; 76 | 77 | int n = sizeof(arr) / sizeof(arr[0]); 78 | 79 | // Function call 80 | cout << "Maximum value we can obtain = " 81 | << fractionalKnapsack(W, arr, n); 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /Greedy/05_fractional_knapsack_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/fractional-knapsack-1587115620/1 3 | 4 | sol: https://www.geeksforgeeks.org/fractional-knapsack-problem/ 5 | */ 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | /* 10 | TC: O(N) 11 | */ 12 | // C/C++ program to solve fractional Knapsack Problem 13 | #include 14 | 15 | using namespace std; 16 | 17 | // Structure for an item which stores weight and 18 | // corresponding value of Item 19 | struct Item { 20 | int value, weight; 21 | 22 | // Constructor 23 | Item(int value, int weight) 24 | { 25 | this->value = value; 26 | this->weight = weight; 27 | } 28 | }; 29 | 30 | // Comparison function to sort Item according to val/weight 31 | // ratio 32 | bool cmp(struct Item a, struct Item b) 33 | { 34 | double r1 = (double)a.value / (double)a.weight; 35 | double r2 = (double)b.value / (double)b.weight; 36 | return r1 > r2; 37 | } 38 | 39 | // Main greedy function to solve problem 40 | double fractionalKnapsack(int W, struct Item arr[], int n) 41 | { 42 | // sorting Item on basis of ratio 43 | sort(arr, arr + n, cmp); 44 | 45 | int curWeight = 0; // Current weight in knapsack 46 | double finalvalue = 0.0; // Result (value in Knapsack) 47 | 48 | // Looping through all Items 49 | for (int i = 0; i < n; i++) { 50 | // If adding Item won't overflow, add it completely 51 | if (curWeight + arr[i].weight <= W) { 52 | curWeight += arr[i].weight; 53 | finalvalue += arr[i].value; 54 | } 55 | 56 | // If we can't add current Item, add fractional part 57 | // of it 58 | else { 59 | int remain = W - curWeight; 60 | finalvalue += arr[i].value 61 | * ((double)remain 62 | / (double)arr[i].weight); 63 | break; 64 | } 65 | } 66 | 67 | // Returning final value 68 | return finalvalue; 69 | } 70 | 71 | // Driver code 72 | int main() 73 | { 74 | int W = 50; // Weight of knapsack 75 | Item arr[] = { { 60, 10 }, { 100, 20 }, { 120, 30 } }; 76 | 77 | int n = sizeof(arr) / sizeof(arr[0]); 78 | 79 | // Function call 80 | cout << "Maximum value we can obtain = " 81 | << fractionalKnapsack(W, arr, n); 82 | return 0; 83 | } 84 | -------------------------------------------------------------------------------- /GREEDY/31_K_centers_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/k-centers-problem-set-1-greedy-approximate-algorithm/ 3 | 4 | The greedy solution works only if the distances between cities follow 5 | Triangular Inequality (Distance between two points is always smaller 6 | than sum of distances through a third point). 7 | */ 8 | 9 | 10 | // ----------------------------------------------------------------------------------------------------------------------- // 11 | // C++ program for the above approach 12 | #include 13 | using namespace std; 14 | 15 | int maxindex(int* dist, int n) 16 | { 17 | int mi = 0; 18 | for (int i = 0; i < n; i++) { 19 | if (dist[i] > dist[mi]) 20 | mi = i; 21 | } 22 | return mi; 23 | } 24 | 25 | void selectKcities(int n, int weights[4][4], int k) 26 | { 27 | int* dist = new int[n]; 28 | vector centers; 29 | for (int i = 0; i < n; i++) { 30 | dist[i] = INT_MAX; 31 | } 32 | 33 | // index of city having the 34 | // maximum distance to it's 35 | // closest center 36 | int max = 0; 37 | for (int i = 0; i < k; i++) { 38 | centers.push_back(max); 39 | for (int j = 0; j < n; j++) { 40 | 41 | // updating the distance 42 | // of the cities to their 43 | // closest centers 44 | dist[j] = min(dist[j], weights[max][j]); 45 | } 46 | 47 | // updating the index of the 48 | // city with the maximum 49 | // distance to it's closest center 50 | max = maxindex(dist, n); 51 | } 52 | 53 | // Printing the maximum distance 54 | // of a city to a center 55 | // that is our answer 56 | cout << endl << dist[max] << endl; 57 | 58 | // Printing the cities that 59 | // were chosen to be made 60 | // centers 61 | for (int i = 0; i < centers.size(); i++) { 62 | cout << centers[i] << " "; 63 | } 64 | cout << endl; 65 | } 66 | 67 | // Driver Code 68 | int main() 69 | { 70 | int n = 4; 71 | int weights[4][4] = { { 0, 4, 8, 5 }, 72 | { 4, 0, 10, 7 }, 73 | { 8, 10, 0, 9 }, 74 | { 5, 7, 9, 0 } }; 75 | int k = 2; 76 | 77 | // Function Call 78 | selectKcities(n, weights, k); 79 | } 80 | -------------------------------------------------------------------------------- /Greedy/31_K_centers_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/k-centers-problem-set-1-greedy-approximate-algorithm/ 3 | 4 | The greedy solution works only if the distances between cities follow 5 | Triangular Inequality (Distance between two points is always smaller 6 | than sum of distances through a third point). 7 | */ 8 | 9 | 10 | // ----------------------------------------------------------------------------------------------------------------------- // 11 | // C++ program for the above approach 12 | #include 13 | using namespace std; 14 | 15 | int maxindex(int* dist, int n) 16 | { 17 | int mi = 0; 18 | for (int i = 0; i < n; i++) { 19 | if (dist[i] > dist[mi]) 20 | mi = i; 21 | } 22 | return mi; 23 | } 24 | 25 | void selectKcities(int n, int weights[4][4], int k) 26 | { 27 | int* dist = new int[n]; 28 | vector centers; 29 | for (int i = 0; i < n; i++) { 30 | dist[i] = INT_MAX; 31 | } 32 | 33 | // index of city having the 34 | // maximum distance to it's 35 | // closest center 36 | int max = 0; 37 | for (int i = 0; i < k; i++) { 38 | centers.push_back(max); 39 | for (int j = 0; j < n; j++) { 40 | 41 | // updating the distance 42 | // of the cities to their 43 | // closest centers 44 | dist[j] = min(dist[j], weights[max][j]); 45 | } 46 | 47 | // updating the index of the 48 | // city with the maximum 49 | // distance to it's closest center 50 | max = maxindex(dist, n); 51 | } 52 | 53 | // Printing the maximum distance 54 | // of a city to a center 55 | // that is our answer 56 | cout << endl << dist[max] << endl; 57 | 58 | // Printing the cities that 59 | // were chosen to be made 60 | // centers 61 | for (int i = 0; i < centers.size(); i++) { 62 | cout << centers[i] << " "; 63 | } 64 | cout << endl; 65 | } 66 | 67 | // Driver Code 68 | int main() 69 | { 70 | int n = 4; 71 | int weights[4][4] = { { 0, 4, 8, 5 }, 72 | { 4, 0, 10, 7 }, 73 | { 8, 10, 0, 9 }, 74 | { 5, 7, 9, 0 } }; 75 | int k = 2; 76 | 77 | // Function Call 78 | selectKcities(n, weights, k); 79 | } 80 | -------------------------------------------------------------------------------- /DP/26_min_cost_to_fill_in_given_weights.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/minimum-cost-to-fill-given-weight-in-a-bag1956/1 3 | 4 | variation of unbounded_knapsack. 5 | 6 | here 1-based index is the weight of the oranges. 7 | */ 8 | 9 | // ----------------------------------------------------------------------------------------------------------------------- // 10 | 11 | int minimumCost(int cost[], int N, int W) 12 | { 13 | 14 | int INF = 999999999; 15 | 16 | // val[] and wt[] arrays 17 | // val[] array to store cost of 'i' kg packet of orange 18 | // wt[] array weight of packet of orange 19 | vector val, wt; 20 | 21 | // traverse the original cost[] array and skip 22 | // unavailable packets and make val[] and wt[] 23 | // array. size variable tells the available number 24 | // of distinct weighted packets 25 | int size = 0; 26 | for (int i = 0; i < N; i++) 27 | { 28 | if (cost[i] != -1) 29 | { 30 | val.push_back(cost[i]); 31 | wt.push_back(i + 1); 32 | size++; 33 | } 34 | } 35 | 36 | N = size; 37 | int min_cost[N + 1][W + 1]; 38 | 39 | // fill 0th row with infinity 40 | for (int i = 0; i <= W; i++) 41 | min_cost[0][i] = INF; 42 | 43 | // fill 0'th column with 0 44 | for (int i = 1; i <= N; i++) 45 | min_cost[i][0] = 0; 46 | 47 | // now check for each weight one by one and fill the 48 | // matrix according to the condition 49 | for (int i = 1; i <= N; i++) 50 | { 51 | for (int j = 1; j <= W; j++) 52 | { 53 | // wt[i-1]>j means capacity of bag is 54 | // less then weight of item 55 | if (wt[i - 1] > j) 56 | min_cost[i][j] = min_cost[i - 1][j]; 57 | 58 | // here we check we get minimum cost either 59 | // by including it or excluding it 60 | else 61 | min_cost[i][j] = min(min_cost[i - 1][j], 62 | min_cost[i][j - wt[i - 1]] + val[i - 1]); 63 | } 64 | } 65 | 66 | // exactly weight W can not be made by given weights 67 | return (min_cost[N][W] == INF) ? -1 : min_cost[N][W]; 68 | } 69 | 70 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /GREEDY/14_find_maximum_meetings_in_one_room.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/find-maximum-meetings-in-one-room/ 3 | */ 4 | 5 | 6 | 7 | // ----------------------------------------------------------------------------------------------------------------------- // 8 | /* 9 | TC: O(N logN) 10 | */ 11 | 12 | // C++ program to find maximum number of meetings 13 | #include 14 | using namespace std; 15 | 16 | // Structure for storing starting time, 17 | // finishing time and position of meeting. 18 | struct meeting { 19 | int start; 20 | int end; 21 | int pos; 22 | }; 23 | 24 | // Comparator function which can compare 25 | // the second element of structure used to 26 | // sort pairs in increasing order of second value. 27 | bool comparator(struct meeting m1, meeting m2) 28 | { 29 | return (m1.end < m2.end); 30 | } 31 | 32 | // Function for finding maximum meeting in one room 33 | void maxMeeting(int s[], int f[], int n) 34 | { 35 | struct meeting meet[n]; 36 | for (int i = 0; i < n; i++) 37 | { 38 | // Starting time of meeting i. 39 | meet[i].start = s[i]; 40 | 41 | // Finishing time of meeting i 42 | meet[i].end = f[i]; 43 | 44 | // Original position/index of meeting 45 | meet[i].pos = i + 1; 46 | } 47 | 48 | // Sorting of meeting according to their finish time. 49 | sort(meet, meet + n, comparator); 50 | 51 | // Vector for storing selected meeting. 52 | vector m; 53 | 54 | // Initially select first meeting. 55 | m.push_back(meet[0].pos); 56 | 57 | // time_limit to check whether new 58 | // meeting can be conducted or not. 59 | int time_limit = meet[0].end; 60 | 61 | // Check for all meeting whether it 62 | // can be selected or not. 63 | for (int i = 1; i < n; i++) { 64 | if (meet[i].start >= time_limit) 65 | { 66 | // Push selected meeting to vector 67 | m.push_back(meet[i].pos); 68 | 69 | // Update time limit. 70 | time_limit = meet[i].end; 71 | } 72 | } 73 | 74 | // Print final selected meetings. 75 | for (int i = 0; i < m.size(); i++) { 76 | cout << m[i] << " "; 77 | } 78 | } 79 | 80 | // Driver code 81 | int main() 82 | { 83 | // Starting time 84 | int s[] = { 1, 3, 0, 5, 8, 5 }; 85 | 86 | // Finish time 87 | int f[] = { 2, 4, 6, 7, 9, 9 }; 88 | 89 | // Number of meetings. 90 | int n = sizeof(s) / sizeof(s[0]); 91 | 92 | // Function call 93 | maxMeeting(s, f, n); 94 | 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /Greedy/14_find_maximum_meetings_in_one_room.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/find-maximum-meetings-in-one-room/ 3 | */ 4 | 5 | 6 | 7 | // ----------------------------------------------------------------------------------------------------------------------- // 8 | /* 9 | TC: O(N logN) 10 | */ 11 | 12 | // C++ program to find maximum number of meetings 13 | #include 14 | using namespace std; 15 | 16 | // Structure for storing starting time, 17 | // finishing time and position of meeting. 18 | struct meeting { 19 | int start; 20 | int end; 21 | int pos; 22 | }; 23 | 24 | // Comparator function which can compare 25 | // the second element of structure used to 26 | // sort pairs in increasing order of second value. 27 | bool comparator(struct meeting m1, meeting m2) 28 | { 29 | return (m1.end < m2.end); 30 | } 31 | 32 | // Function for finding maximum meeting in one room 33 | void maxMeeting(int s[], int f[], int n) 34 | { 35 | struct meeting meet[n]; 36 | for (int i = 0; i < n; i++) 37 | { 38 | // Starting time of meeting i. 39 | meet[i].start = s[i]; 40 | 41 | // Finishing time of meeting i 42 | meet[i].end = f[i]; 43 | 44 | // Original position/index of meeting 45 | meet[i].pos = i + 1; 46 | } 47 | 48 | // Sorting of meeting according to their finish time. 49 | sort(meet, meet + n, comparator); 50 | 51 | // Vector for storing selected meeting. 52 | vector m; 53 | 54 | // Initially select first meeting. 55 | m.push_back(meet[0].pos); 56 | 57 | // time_limit to check whether new 58 | // meeting can be conducted or not. 59 | int time_limit = meet[0].end; 60 | 61 | // Check for all meeting whether it 62 | // can be selected or not. 63 | for (int i = 1; i < n; i++) { 64 | if (meet[i].start >= time_limit) 65 | { 66 | // Push selected meeting to vector 67 | m.push_back(meet[i].pos); 68 | 69 | // Update time limit. 70 | time_limit = meet[i].end; 71 | } 72 | } 73 | 74 | // Print final selected meetings. 75 | for (int i = 0; i < m.size(); i++) { 76 | cout << m[i] << " "; 77 | } 78 | } 79 | 80 | // Driver code 81 | int main() 82 | { 83 | // Starting time 84 | int s[] = { 1, 3, 0, 5, 8, 5 }; 85 | 86 | // Finish time 87 | int f[] = { 2, 4, 6, 7, 9, 9 }; 88 | 89 | // Number of meetings. 90 | int n = sizeof(s) / sizeof(s[0]); 91 | 92 | // Function call 93 | maxMeeting(s, f, n); 94 | 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /BACKTRACKING/17_print_all_possible_path_from_top_left_to_bottom_right_in_MN_matrix.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/print-all-possible-paths-from-top-left-to-bottom-right-of-a-mxn-matrix/ 3 | 4 | note: also refer other 3 code from **link** 5 | */ 6 | 7 | 8 | 9 | // ----------------------------------------------------------------------------------------------------------------------- // 10 | /* 11 | TC: O(2^n*m) 12 | SC: O(n) 13 | */ 14 | #include 15 | using namespace std; 16 | 17 | // function to display the path 18 | void display(vector& ans) { 19 | for (auto i : ans) { 20 | cout << i << " "; 21 | } 22 | cout << endl; 23 | } 24 | 25 | // a function which check whether our step is safe or not 26 | bool issafe(int r, int c, vector>& visited, int n, int m) { 27 | return (r < nand c < mand visited[r] != -1); // return true if all values satisfied else false 28 | } 29 | 30 | 31 | void FindPaths(vector>& grid, int r, int c, int n, int m, vector& ans) { 32 | // when we hit the last cell we reach to destination then direclty push the path 33 | if (r == n - 1 and c == m - 1) { 34 | ans.push_back(grid[r]); 35 | display(ans); // function to display the path stored in ans vector 36 | ans.pop_back(); // pop back because we need to backtrack to explore more path 37 | return; 38 | } 39 | 40 | // we will store the current value in ch and mark the visited place as -1 41 | int ch = grid[r]; 42 | 43 | ans.push_back(ch); // push the path in ans array 44 | grid[r] = -1; // mark the visited place with -1 45 | 46 | // if is it safe to take next downward step then take it 47 | if (issafe(r + 1, c, grid, n, m)) { 48 | FindPaths(grid, r + 1, c, n, m, ans); 49 | } 50 | 51 | // if is it safe to take next rightward step then take it 52 | if (issafe(r, c + 1, grid, n, m)) { 53 | FindPaths(grid, r, c + 1, n, m, ans); 54 | } 55 | 56 | // backtracking step we need to make values original so to we can visit it by some another path 57 | grid[r] = ch; 58 | 59 | // remove the current path element we explore 60 | ans.pop_back(); 61 | return; 62 | } 63 | 64 | int main() { 65 | int n = 3, m = 3; 66 | vector >grid{ {1,2,3},{4,5,6},{7,8,9} }; 67 | vectorans; // it will store the path which we have covered 68 | 69 | FindPaths(grid, 0, 0, n, m, ans); // here 0,0 are initial position to start with 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /TRIE/extra_07_biggest_xor.cpp: -------------------------------------------------------------------------------- 1 | // find biggest xor between any two element 2 | 3 | #include 4 | using namespace std; 5 | 6 | class node { 7 | public: 8 | node* left; // for 0 9 | node* right; // for 1 10 | }; 11 | 12 | class trie { 13 | node* root; 14 | 15 | public: 16 | trie() { 17 | root = new node(); 18 | } 19 | 20 | void insert(int n) { 21 | node* temp = root; 22 | 23 | for (int i = 31;i >= 0;i--) { 24 | int bit = (n >> i) & 1; 25 | if (bit == 0) { 26 | if (temp->left == NULL) { 27 | temp->left = new node(); 28 | } 29 | else temp = temp->left; 30 | } 31 | else { 32 | if (temp->right == NULL) { 33 | temp->right = new node(); 34 | } 35 | else temp = temp->right; 36 | } 37 | } 38 | } 39 | 40 | int max_xor_helper(int value) { 41 | int current_ans = 0; 42 | node* temp = root; 43 | 44 | for (int i = 31;i >= 0;i++) { 45 | int bit = (value >> i) & i; 46 | 47 | if (bit == 0) { 48 | if (temp->right != NULL) { 49 | temp = temp->right; 50 | current_ans += (1 << i); 51 | } 52 | else { 53 | temp = temp->left; 54 | } 55 | } 56 | else { 57 | if (temp->left != NULL) { 58 | temp = temp->left; 59 | current_ans += (1 << i); 60 | } 61 | else { 62 | temp = temp->right; 63 | } 64 | } 65 | } 66 | return current_ans; 67 | } 68 | 69 | int max_xor(int* input, int n) { 70 | int max_xor = 0; 71 | for (int i = 0;i < n;i++) { 72 | int value = input[i]; 73 | insert(value); 74 | int current_xor = max_xor_helper(value); 75 | max_xor = max(max_xor, current_xor); 76 | } 77 | return max_xor; 78 | } 79 | }; 80 | 81 | 82 | int main() { 83 | 84 | trie t; 85 | 86 | int input[] = { 3, 10, 5, 3, 7 }; 87 | int n = sizeof(input) / sizeof(input[0]); 88 | 89 | cout << t.max_xor(input, n); 90 | 91 | return 0; 92 | } -------------------------------------------------------------------------------- /TRIE/extra_06_cute_cat.cpp: -------------------------------------------------------------------------------- 1 | // does given words exist or is substring in docuement 2 | 3 | #include 4 | using namespace std; 5 | 6 | class Node { 7 | public: 8 | char data; 9 | unordered_map m; 10 | bool isTerminal; 11 | 12 | Node(char d) { 13 | data = d; 14 | isTerminal = false; 15 | } 16 | }; 17 | 18 | class Trie { 19 | public: 20 | Node* root; 21 | Trie() { 22 | root = new Node('\0'); 23 | } 24 | 25 | void insert(string word) { 26 | Node* temp = root; 27 | 28 | for (char ch : word) { 29 | if (temp->m.count(ch) == 0) { 30 | temp->m[ch] = new Node(ch); 31 | } 32 | temp = temp->m[ch]; 33 | } 34 | temp->isTerminal = true; 35 | } 36 | 37 | bool search(string word) { 38 | Node* temp = root; 39 | 40 | for (char ch : word) { 41 | if (temp->m.count(ch) == 0) return false; 42 | temp = temp->m[ch]; 43 | } 44 | return temp->isTerminal; 45 | } 46 | }; 47 | 48 | void searchHelper(Trie t, string document, int i, unordered_map& isPresent) { 49 | Node* temp = t.root; 50 | 51 | for (int j = i; j < document.length(); j++) { 52 | char ch = document[j]; 53 | if (temp->m.count(ch) == 0) return; 54 | 55 | temp = temp->m[ch]; 56 | if (temp->isTerminal) { 57 | string out = document.substr(i, j - i + 1); 58 | isPresent[out] = true; 59 | } 60 | } 61 | return; 62 | } 63 | 64 | void documentSearch(string document, string words) { 65 | 66 | // 1. create trie by inserting words 67 | Trie t; 68 | for (auto w : words) { 69 | t.insert(w); 70 | } 71 | 72 | // 2. searching (Helper fun.) 73 | unordered_map isPresent; 74 | for (int i = 0; i < document.length(); i++) { 75 | searchHelper(t, document, i, isPresent); 76 | } 77 | 78 | // 3. check which are present or and which not 79 | for (auto w : words) { 80 | if (isPresent.count(w) == 0) cout << "False" << endl; 81 | else cout << "True" << endl; 82 | } 83 | } 84 | 85 | int main() { 86 | string document = "little cute cat loves to code in c++, java & python"; 87 | string words[5] = { "cute cat", "ttle", "cat", "quick", "big" }; 88 | 89 | documentSearch(document, words); 90 | 91 | } -------------------------------------------------------------------------------- /BACKTRACKING/07_print_all_palindromic_partitions_of_string.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/given-a-string-print-all-possible-palindromic-partition/ 3 | 4 | video: https://youtu.be/WBgsABoClE0 5 | */ 6 | 7 | 8 | 9 | // ----------------------------------------------------------------------------------------------------------------------- // 10 | bool isPalindrome(string s, int start, int end) { 11 | while (start <= end) { 12 | if (s[start++] != s[end--]) return false; 13 | } 14 | return true; 15 | } 16 | 17 | void recur(int index, string s, vector& path, vector>& res) { 18 | if (index == s.size()) { 19 | res.push_back(path); 20 | return; 21 | } 22 | 23 | for (int i = index, i < s.size(); i++) { 24 | if (isPalindrome(s, index, i)) { 25 | path.push_back(s.substr(index, i - index + 1)); 26 | recur(i + 1, s, path, res); 27 | path.pop_back(); 28 | } 29 | } 30 | } 31 | 32 | vector> partition(string s) { 33 | vector> res; 34 | vector path; 35 | recur(0, s, path, res); 36 | return res; 37 | } 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | // ----------------------------------------------------------------------------------------------------------------------- // 46 | /* 47 | another solution 48 | */ 49 | 50 | vector vs; 51 | 52 | // function to check palindrom 53 | bool isPalindrome(string s) { 54 | int n = s.size(); 55 | for (int i = 0; i < n / 2; i++) { 56 | if (s[i] != s[n - 1 - i]) return false; 57 | } 58 | return true; 59 | } 60 | 61 | // recuring func. 62 | void recur(string s, string ans) { 63 | // if there is nothing left to check in string 64 | if (s.size() == 0) { 65 | // substr is used just to remove extra space at the end 66 | // also push the ans string as it contains the all the palindromic substr 67 | vs.push_back(ans.substr(0, ans.size() - 1)); 68 | return; 69 | } 70 | 71 | // checking for every partition in our current string 72 | for (int i = 0; i < s.size(); i++) { 73 | string left = s.substr(0, i + 1); 74 | 75 | // if left substring is palindromic then and only then 76 | if (isPalindrome(left)) { 77 | string right = s.substr(i + 1); 78 | // pass the right substring in s and add left to the ans 79 | recur(right, ans + left + " ") 80 | } 81 | } 82 | } 83 | 84 | vector backtracking(string s) { 85 | vs.clear(); 86 | int n = s.size(); 87 | 88 | recur(s, ""); 89 | return vs; 90 | } -------------------------------------------------------------------------------- /GREEDY/12_min_cost_to_cut_board_into_square.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/minimum-cost-cut-board-squares/ 3 | 4 | video (just for understanding): https://youtu.be/9DckVBRzuQU 5 | 6 | initially board is altogether, but after each cut it will be divided and furthur cuts will be made on the basis of different grouped sections 7 | 8 | eg. 9 | - - - - 10 | - - - - 11 | - - - - 12 | - - - - 13 | 14 | after cut in row sections will be like 15 | 16 | - - - - 17 | - - - - 18 | - - - - 19 | 20 | - - - - 21 | 22 | 23 | after cut in column sections will be like 24 | - - - - 25 | - - - - 26 | - - - - 27 | 28 | - - - - 29 | 30 | 31 | and hence cost will be accordingly 32 | 33 | */ 34 | 35 | 36 | // ----------------------------------------------------------------------------------------------------------------------- // 37 | // C++ program to divide a board into m*n squares 38 | #include 39 | using namespace std; 40 | 41 | // method returns minimum cost to break board into 42 | // m*n squares 43 | int minimumCostOfBreaking(int X[], int Y[], int m, int n) 44 | { 45 | int res = 0; 46 | 47 | // sort the horizontal cost in reverse order 48 | sort(X, X + m, greater()); 49 | 50 | // sort the vertical cost in reverse order 51 | sort(Y, Y + n, greater()); 52 | 53 | // initialize current width as 1 54 | int hzntl = 1, vert = 1; 55 | 56 | // loop untill one or both cost array are processed 57 | int i = 0, j = 0; 58 | while (i < m && j < n) 59 | { 60 | if (X[i] > Y[j]) 61 | { 62 | res += X[i] * vert; 63 | 64 | // increase current horizontal part count by 1 65 | hzntl++; 66 | i++; 67 | } 68 | else 69 | { 70 | res += Y[j] * hzntl; 71 | 72 | // increase current vertical part count by 1 73 | vert++; 74 | j++; 75 | } 76 | } 77 | 78 | // loop for horizontal array, if remains 79 | int total = 0; 80 | while (i < m) 81 | total += X[i++]; 82 | res += total * vert; 83 | 84 | // loop for vertical array, if remains 85 | total = 0; 86 | while (j < n) 87 | total += Y[j++]; 88 | res += total * hzntl; 89 | 90 | return res; 91 | } 92 | 93 | // Driver code to test above methods 94 | int main() 95 | { 96 | int m = 6, n = 4; 97 | int X[m - 1] = { 2, 1, 3, 1, 4 }; 98 | int Y[n - 1] = { 4, 1, 2 }; 99 | cout << minimumCostOfBreaking(X, Y, m - 1, n - 1); 100 | return 0; 101 | } 102 | -------------------------------------------------------------------------------- /Greedy/12_min_cost_to_cut_board_into_square.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/minimum-cost-cut-board-squares/ 3 | 4 | video (just for understanding): https://youtu.be/9DckVBRzuQU 5 | 6 | initially board is altogether, but after each cut it will be divided and furthur cuts will be made on the basis of different grouped sections 7 | 8 | eg. 9 | - - - - 10 | - - - - 11 | - - - - 12 | - - - - 13 | 14 | after cut in row sections will be like 15 | 16 | - - - - 17 | - - - - 18 | - - - - 19 | 20 | - - - - 21 | 22 | 23 | after cut in column sections will be like 24 | - - - - 25 | - - - - 26 | - - - - 27 | 28 | - - - - 29 | 30 | 31 | and hence cost will be accordingly 32 | 33 | */ 34 | 35 | 36 | // ----------------------------------------------------------------------------------------------------------------------- // 37 | // C++ program to divide a board into m*n squares 38 | #include 39 | using namespace std; 40 | 41 | // method returns minimum cost to break board into 42 | // m*n squares 43 | int minimumCostOfBreaking(int X[], int Y[], int m, int n) 44 | { 45 | int res = 0; 46 | 47 | // sort the horizontal cost in reverse order 48 | sort(X, X + m, greater()); 49 | 50 | // sort the vertical cost in reverse order 51 | sort(Y, Y + n, greater()); 52 | 53 | // initialize current width as 1 54 | int hzntl = 1, vert = 1; 55 | 56 | // loop untill one or both cost array are processed 57 | int i = 0, j = 0; 58 | while (i < m && j < n) 59 | { 60 | if (X[i] > Y[j]) 61 | { 62 | res += X[i] * vert; 63 | 64 | // increase current horizontal part count by 1 65 | hzntl++; 66 | i++; 67 | } 68 | else 69 | { 70 | res += Y[j] * hzntl; 71 | 72 | // increase current vertical part count by 1 73 | vert++; 74 | j++; 75 | } 76 | } 77 | 78 | // loop for horizontal array, if remains 79 | int total = 0; 80 | while (i < m) 81 | total += X[i++]; 82 | res += total * vert; 83 | 84 | // loop for vertical array, if remains 85 | total = 0; 86 | while (j < n) 87 | total += Y[j++]; 88 | res += total * hzntl; 89 | 90 | return res; 91 | } 92 | 93 | // Driver code to test above methods 94 | int main() 95 | { 96 | int m = 6, n = 4; 97 | int X[m - 1] = { 2, 1, 3, 1, 4 }; 98 | int Y[n - 1] = { 4, 1, 2 }; 99 | cout << minimumCostOfBreaking(X, Y, m - 1, n - 1); 100 | return 0; 101 | } 102 | -------------------------------------------------------------------------------- /DP/38_interleaved_string.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/interleaved-strings/1 3 | 4 | although its LCS variation but tweaked code of it will not work here. 5 | */ 6 | 7 | // ----------------------------------------------------------------------------------------------------------------------- // 8 | 9 | bool isInterleave(string A, string B, string C) 10 | { 11 | // Find lengths of the two strings 12 | int M = A.size(), N = B.size(); 13 | 14 | // Let us create a 2D table to store solutions of 15 | // subproblems. C[i][j] will be true if C[0..i+j-1] 16 | // is an interleaving of A[0..i-1] and B[0..j-1]. 17 | bool IL[M + 1][N + 1]; 18 | 19 | memset(IL, 0, sizeof(IL)); // Initialize all values as false. 20 | 21 | // C can be an interleaving of A and B only of sum 22 | // of lengths of A & B is equal to length of C. 23 | if ((M + N) != C.size()) 24 | return false; 25 | 26 | // Process all characters of A and B 27 | for (int i = 0; i <= M; ++i) 28 | { 29 | for (int j = 0; j <= N; ++j) 30 | { 31 | // two empty strings have an empty string 32 | // as interleaving 33 | if (i == 0 && j == 0) 34 | IL[i][j] = true; 35 | 36 | // A is empty 37 | else if (i == 0 && B[j - 1] == C[j - 1]) 38 | IL[i][j] = IL[i][j - 1]; 39 | 40 | // B is empty 41 | else if (j == 0 && A[i - 1] == C[i - 1]) 42 | IL[i][j] = IL[i - 1][j]; 43 | 44 | // Current character of C matches with current character of A, 45 | // but doesn't match with current character of B 46 | else if (A[i - 1] == C[i + j - 1] && B[j - 1] != C[i + j - 1]) 47 | IL[i][j] = IL[i - 1][j]; 48 | 49 | // Current character of C matches with current character of B, 50 | // but doesn't match with current character of A 51 | else if (A[i - 1] != C[i + j - 1] && B[j - 1] == C[i + j - 1]) 52 | IL[i][j] = IL[i][j - 1]; 53 | 54 | // Current character of C matches with that of both A and B 55 | else if (A[i - 1] == C[i + j - 1] && B[j - 1] == C[i + j - 1]) 56 | IL[i][j] = (IL[i - 1][j] || IL[i][j - 1]); 57 | } 58 | } 59 | 60 | return IL[M][N]; 61 | } 62 | 63 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /DP/45_palindrom_partition_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/palindromic-patitioning4845/1 3 | 4 | video: https://www.youtube.com/watch?v=qmTtAbOTqcg 5 | */ 6 | 7 | // ----------------------------------------------------------------------------------------------------------------------- // 8 | 9 | // tabulation 10 | // TC: O(N^2) 11 | int MCM(string s) { 12 | int n = s.size(); 13 | bool dp[n][n]; 14 | 15 | for (int gap = 0;gap < n;gap++) { 16 | for (int i = 0, j = gap;j < n;i++, j++) { 17 | if (gap == 0) { 18 | dp[i][j] = true; 19 | } 20 | else if (gap == 1) { 21 | dp[i][j] = (s[i] == s[j]); 22 | } 23 | else { 24 | if (s[i] == s[j] && dp[i + 1][j - 1] == true) { 25 | dp[i][j] = true; 26 | } 27 | else { 28 | dp[i][j] = false; 29 | } 30 | } 31 | } 32 | } 33 | 34 | // will be O(N^3) 35 | /* int cut[n][n]; 36 | for (int gap = 0;gap < n;gap++) { 37 | for (int i = 0, j = gap;j < n;i++, j++) { 38 | if (gap == 0) { 39 | cut[i][j] = 0; 40 | } 41 | else if (gap == 1) { 42 | if (s[i] == s[j]) { 43 | cut[i][j] = 0; 44 | } 45 | else cut[i][j] = 1; 46 | } 47 | else { 48 | if (dp[i][j]) cut[i][j] = 0; 49 | else { 50 | int mn = INT_MAX; 51 | for (int k = 1;k < j;k++) { 52 | int left = cut[i][k]; 53 | int right = cut[k + 1][j]; 54 | mn = min(1 + left + right); 55 | } 56 | cut[i][j] = mn; 57 | } 58 | } 59 | } 60 | } */ 61 | int cut[n]; 62 | cut[0] = 0; 63 | for (int gap = 1;gap < n;gap++) { 64 | if (dp[0][gap]) cut[gap] = 0; 65 | else { 66 | int mn = INT_MAX; 67 | for (int i = gap;i >= 0;i--) { 68 | if (dp[i][gap]) { 69 | mn = min(mn, cut[i - 1]); 70 | } 71 | } 72 | cut[gap] = mn + 1; 73 | } 74 | } 75 | 76 | 77 | return cut[n - 1]; 78 | } 79 | 80 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /DP/48_weighted_job_scheduling.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/weighted-job-scheduling/ 3 | 4 | variation of 0/1 knapsack 5 | 6 | source code is there in link. 7 | */ 8 | 9 | // ----------------------------------------------------------------------------------------------------------------------- // 10 | 11 | // C++ program for weighted job scheduling using Dynamic Programming. 12 | #include 13 | #include 14 | using namespace std; 15 | 16 | // A job has start time, finish time and profit. 17 | struct Job 18 | { 19 | int start, finish, profit; 20 | }; 21 | 22 | // A utility function that is used for sorting events 23 | // according to finish time 24 | bool jobComparataor(Job s1, Job s2) 25 | { 26 | return (s1.finish < s2.finish); 27 | } 28 | 29 | // Find the latest job (in sorted array) that doesn't 30 | // conflict with the job[i] 31 | int latestNonConflict(Job arr[], int i) 32 | { 33 | for (int j = i - 1; j >= 0; j--) 34 | { 35 | if (arr[j].finish <= arr[i].start) 36 | return j; 37 | } 38 | return -1; 39 | } 40 | 41 | // The main function that returns the maximum possible 42 | // profit from given array of jobs 43 | int findMaxProfit(Job arr[], int n) 44 | { 45 | // Sort jobs according to finish time 46 | sort(arr, arr + n, jobComparataor); 47 | 48 | // Create an array to store solutions of subproblems. table[i] 49 | // stores the profit for jobs till arr[i] (including arr[i]) 50 | int* table = new int[n]; 51 | table[0] = arr[0].profit; 52 | 53 | // Fill entries in M[] using recursive property 54 | for (int i = 1; i < n; i++) 55 | { 56 | // Find profit including the current job 57 | int inclProf = arr[i].profit; 58 | int l = latestNonConflict(arr, i); 59 | if (l != -1) 60 | inclProf += table[l]; 61 | 62 | // Store maximum of including and excluding 63 | table[i] = max(inclProf, table[i - 1]); 64 | } 65 | 66 | // Store result and free dynamic memory allocated for table[] 67 | int result = table[n - 1]; 68 | delete[] table; 69 | 70 | return result; 71 | } 72 | 73 | // Driver program 74 | int main() 75 | { 76 | Job arr[] = { {3, 10, 20}, {1, 2, 50}, {6, 19, 100}, {2, 100, 200} }; 77 | int n = sizeof(arr) / sizeof(arr[0]); 78 | cout << "The optimal profit is " << findMaxProfit(arr, n); 79 | return 0; 80 | } 81 | 82 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /GREEDY/22_least_recently_used_LRU_page_replacement.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/page-faults-in-lru5603/1 3 | 4 | sol: https://www.geeksforgeeks.org/program-for-least-recently-used-lru-page-replacement-algorithm/ 5 | */ 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | //C++ implementation of above algorithm 10 | #include 11 | using namespace std; 12 | 13 | // Function to find page faults using indexes 14 | int pageFaults(int pages[], int n, int capacity) 15 | { 16 | // To represent set of current pages. We use 17 | // an unordered_set so that we quickly check 18 | // if a page is present in set or not 19 | unordered_set s; 20 | 21 | // To store least recently used indexes 22 | // of pages. 23 | unordered_map indexes; 24 | 25 | // Start from initial page 26 | int page_faults = 0; 27 | for (int i = 0; i < n; i++) 28 | { 29 | // Check if the set can hold more pages 30 | if (s.size() < capacity) 31 | { 32 | // Insert it into set if not present 33 | // already which represents page fault 34 | if (s.find(pages[i]) == s.end()) 35 | { 36 | s.insert(pages[i]); 37 | 38 | // increment page fault 39 | page_faults++; 40 | } 41 | 42 | // Store the recently used index of 43 | // each page 44 | indexes[pages[i]] = i; 45 | } 46 | 47 | // If the set is full then need to perform lru 48 | // i.e. remove the least recently used page 49 | // and insert the current page 50 | else 51 | { 52 | // Check if current page is not already 53 | // present in the set 54 | if (s.find(pages[i]) == s.end()) 55 | { 56 | // Find the least recently used pages 57 | // that is present in the set 58 | int lru = INT_MAX, val; 59 | for (auto it = s.begin(); it != s.end(); it++) 60 | { 61 | if (indexes[*it] < lru) 62 | { 63 | lru = indexes[*it]; 64 | val = *it; 65 | } 66 | } 67 | 68 | // Remove the indexes page 69 | s.erase(val); 70 | 71 | // insert the current page 72 | s.insert(pages[i]); 73 | 74 | // Increment page faults 75 | page_faults++; 76 | } 77 | 78 | // Update the current page index 79 | indexes[pages[i]] = i; 80 | } 81 | } 82 | 83 | return page_faults; 84 | } 85 | 86 | // Driver code 87 | int main() 88 | { 89 | int pages[] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2 }; 90 | int n = sizeof(pages) / sizeof(pages[0]); 91 | int capacity = 4; 92 | cout << pageFaults(pages, n, capacity); 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /Greedy/22_least_recently_used_LRU_page_replacement.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/page-faults-in-lru5603/1 3 | 4 | sol: https://www.geeksforgeeks.org/program-for-least-recently-used-lru-page-replacement-algorithm/ 5 | */ 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | //C++ implementation of above algorithm 10 | #include 11 | using namespace std; 12 | 13 | // Function to find page faults using indexes 14 | int pageFaults(int pages[], int n, int capacity) 15 | { 16 | // To represent set of current pages. We use 17 | // an unordered_set so that we quickly check 18 | // if a page is present in set or not 19 | unordered_set s; 20 | 21 | // To store least recently used indexes 22 | // of pages. 23 | unordered_map indexes; 24 | 25 | // Start from initial page 26 | int page_faults = 0; 27 | for (int i = 0; i < n; i++) 28 | { 29 | // Check if the set can hold more pages 30 | if (s.size() < capacity) 31 | { 32 | // Insert it into set if not present 33 | // already which represents page fault 34 | if (s.find(pages[i]) == s.end()) 35 | { 36 | s.insert(pages[i]); 37 | 38 | // increment page fault 39 | page_faults++; 40 | } 41 | 42 | // Store the recently used index of 43 | // each page 44 | indexes[pages[i]] = i; 45 | } 46 | 47 | // If the set is full then need to perform lru 48 | // i.e. remove the least recently used page 49 | // and insert the current page 50 | else 51 | { 52 | // Check if current page is not already 53 | // present in the set 54 | if (s.find(pages[i]) == s.end()) 55 | { 56 | // Find the least recently used pages 57 | // that is present in the set 58 | int lru = INT_MAX, val; 59 | for (auto it = s.begin(); it != s.end(); it++) 60 | { 61 | if (indexes[*it] < lru) 62 | { 63 | lru = indexes[*it]; 64 | val = *it; 65 | } 66 | } 67 | 68 | // Remove the indexes page 69 | s.erase(val); 70 | 71 | // insert the current page 72 | s.insert(pages[i]); 73 | 74 | // Increment page faults 75 | page_faults++; 76 | } 77 | 78 | // Update the current page index 79 | indexes[pages[i]] = i; 80 | } 81 | } 82 | 83 | return page_faults; 84 | } 85 | 86 | // Driver code 87 | int main() 88 | { 89 | int pages[] = { 7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2 }; 90 | int n = sizeof(pages) / sizeof(pages[0]); 91 | int capacity = 4; 92 | cout << pageFaults(pages, n, capacity); 93 | return 0; 94 | } 95 | -------------------------------------------------------------------------------- /TRIE/extra_04_longest_duplicate_sub_string.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://youtu.be/FQ8hcOOzQMU?list=PLEJXowNB4kPyi859E6qGUs7jlpQehJndl 3 | */ 4 | 5 | 6 | // ----------------------------------------------------------------------------------------------------------------------- // 7 | #define p 10000007 8 | //#define lli long long int 9 | 10 | vector roll; 11 | 12 | class Solution { 13 | bool match(string s, int len, int size, string& ans) 14 | { 15 | unordered_map> m; //Key->hashValue...Value->starting index of substring 16 | int hash = 0; //curr window hash 17 | for (int i = 0;i < size;++i) 18 | hash = (hash * 26 + (s[i] - 'a')) % p; 19 | 20 | m[hash].push_back(0); 21 | //Rolling hash (sliding window) 22 | for (int j = size;j < len;++j) 23 | { 24 | hash = ((hash - roll[size - 1] * (s[j - size] - 'a')) % p + p) % p; 25 | hash = (hash * 26 + (s[j] - 'a')) % p; 26 | if (m.find(hash) != m.end()) 27 | { 28 | for (auto start : m[hash]) 29 | { 30 | string temp = s.substr(start, size); 31 | string curr = s.substr(j - size + 1, size); 32 | if (temp.compare(curr) == 0) 33 | { 34 | ans = temp; 35 | return true; 36 | } 37 | } 38 | } 39 | m[hash].push_back(j - size + 1); 40 | } 41 | return false; 42 | } 43 | 44 | public: 45 | string longestDupSubstring(string S) { 46 | ios_base::sync_with_stdio(false); 47 | cin.tie(NULL); 48 | 49 | int len = S.size(); 50 | if (len == 0) 51 | return ""; 52 | 53 | //Store all rolling hash values 54 | roll.resize(len); //Allocating fixed space to array 55 | roll[0] = 1; //Since 26^0 = 1 56 | for (int i = 1;i < len;++i) 57 | roll[i] = (26 * roll[i - 1]) % p; 58 | 59 | int low = 1, high = len, mid; 60 | string ans = "", temp; 61 | while (low <= high) 62 | { 63 | temp = ""; 64 | mid = low + (high - low) / 2; 65 | bool flag = match(S, len, mid, temp); 66 | if (flag) 67 | { 68 | if (temp.size() > ans.size()) 69 | ans = temp; 70 | low = mid + 1; 71 | } 72 | else 73 | high = mid - 1; 74 | } 75 | return ans; 76 | } 77 | }; -------------------------------------------------------------------------------- /GREEDY/26_die_hard.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.spoj.com/problems/DIEHARD/ 3 | 4 | video: https://youtu.be/KrXzcYTDn2s 5 | */ 6 | 7 | 8 | 9 | // ----------------------------------------------------------------------------------------------------------------------- // 10 | /* 11 | greedy solution 12 | */ 13 | #include 14 | using namespace std; 15 | 16 | int main() { 17 | int t; 18 | cin >> t; 19 | while (t--) { 20 | int h, a; 21 | cin >> h >> a; 22 | 23 | int ans = 0; 24 | 25 | while (h > 0 && a > 0) { 26 | // everytime we will come to air as it increase our health as well as armour 27 | h += 3; 28 | a += 2; 29 | ans++; 30 | 31 | // if armour is about to damaged (0). then choose fire as it will increase armour 32 | if (a <= 10) { 33 | h -= 20; 34 | a += 5; 35 | } 36 | // else choose water. 37 | else { 38 | h -= 5; 39 | a -= 10; 40 | } 41 | // if still both met condition then increase ans as we got more unit time. 42 | if (h > 0 && a > 0) ans++; 43 | } 44 | cout << ans << endl; 45 | } 46 | } 47 | 48 | 49 | 50 | 51 | 52 | 53 | // ----------------------------------------------------------------------------------------------------------------------- // 54 | /* 55 | DP solution 56 | */ 57 | #include 58 | #define int long long int 59 | #define pb push_back 60 | #define ps(x,y) fixed<>x; while(x--) 63 | using namespace std; 64 | 65 | int dp[1001][1001]; 66 | 67 | int solve(int h, int a, int i) { 68 | if (h <= 0 or a <= 0) 69 | return 0; 70 | if (dp[h][a] != -1) { 71 | // cout<<"Found "<> t; 87 | while (t--) { 88 | int health, armor; 89 | cin >> health >> armor; 90 | memset(dp, -1, sizeof(dp)); 91 | cout << max({ solve(health + 3,armor + 2,1),solve(health - 5,armor - 10,2),solve(health - 20,armor + 5,3) }) << endl; 92 | } 93 | 94 | return 0; 95 | } -------------------------------------------------------------------------------- /Greedy/26_die_hard.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.spoj.com/problems/DIEHARD/ 3 | 4 | video: https://youtu.be/KrXzcYTDn2s 5 | */ 6 | 7 | 8 | 9 | // ----------------------------------------------------------------------------------------------------------------------- // 10 | /* 11 | greedy solution 12 | */ 13 | #include 14 | using namespace std; 15 | 16 | int main() { 17 | int t; 18 | cin >> t; 19 | while (t--) { 20 | int h, a; 21 | cin >> h >> a; 22 | 23 | int ans = 0; 24 | 25 | while (h > 0 && a > 0) { 26 | // everytime we will come to air as it increase our health as well as armour 27 | h += 3; 28 | a += 2; 29 | ans++; 30 | 31 | // if armour is about to damaged (0). then choose fire as it will increase armour 32 | if (a <= 10) { 33 | h -= 20; 34 | a += 5; 35 | } 36 | // else choose water. 37 | else { 38 | h -= 5; 39 | a -= 10; 40 | } 41 | // if still both met condition then increase ans as we got more unit time. 42 | if (h > 0 && a > 0) ans++; 43 | } 44 | cout << ans << endl; 45 | } 46 | } 47 | 48 | 49 | 50 | 51 | 52 | 53 | // ----------------------------------------------------------------------------------------------------------------------- // 54 | /* 55 | DP solution 56 | */ 57 | #include 58 | #define int long long int 59 | #define pb push_back 60 | #define ps(x,y) fixed<>x; while(x--) 63 | using namespace std; 64 | 65 | int dp[1001][1001]; 66 | 67 | int solve(int h, int a, int i) { 68 | if (h <= 0 or a <= 0) 69 | return 0; 70 | if (dp[h][a] != -1) { 71 | // cout<<"Found "<> t; 87 | while (t--) { 88 | int health, armor; 89 | cin >> health >> armor; 90 | memset(dp, -1, sizeof(dp)); 91 | cout << max({ solve(health + 3,armor + 2,1),solve(health - 5,armor - 10,2),solve(health - 20,armor + 5,3) }) << endl; 92 | } 93 | 94 | return 0; 95 | } -------------------------------------------------------------------------------- /DP/37_longest_alternating_subsequence.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/longest-alternating-subsequence5951/1 3 | 4 | sol: from above link's sol only 5 | */ 6 | 7 | // ----------------------------------------------------------------------------------------------------------------------- // 8 | 9 | // recursive solution to understand 10 | class Solution { 11 | public: 12 | int helper(vector& nums, int i, bool isIncre) { 13 | // base condition 14 | if (i == nums.size()) return 0; 15 | // two different type of pattern hence incre or decre, also either include or not the current ele. 16 | if (i == 0) { 17 | return max({ 1 + helper(nums,i + 1,0), 1 + helper(nums,i + 1, 1), helper(nums,i + 1,0), helper(nums,i + 1, 1) }) 18 | } 19 | 20 | 21 | int a = 0, b = 0, c = 0, d = 0; 22 | if (isIncre) { 23 | if (nums[i - 1] < nums[i]) { 24 | // now 2 possibilities either include the element or not and as we got incre this time hence pass decre this time. 25 | return max(1 + helper(nums, i + 1, 0), helper(nums, i + 1, 0)); 26 | } 27 | else { 28 | // as our condition wasn't met hence ignore the current element. 29 | return helper(nums, i + 1, 1); 30 | } 31 | } 32 | else { 33 | if (nums[i - 1] > nums[i]) { 34 | a = 1 + helper(nums, i + 1, 1); 35 | c = helper(nums, i + 1, 1); 36 | } 37 | else { 38 | d = helper(nums, i + 1, 0); 39 | } 40 | } 41 | return max({ a, b, c, d }); 42 | } 43 | 44 | int AlternatingaMaxLength(vector& nums) { 45 | 46 | return helper(nums, 1, 1); 47 | } 48 | }; 49 | 50 | // ----------------------------------------------------------------------------------------------------------------------- // 51 | 52 | // most optimized sol. 53 | // TC: O(N); 54 | int AlternatingaMaxLength(vector& nums) { 55 | if (nums.size() < 2) 56 | return nums.size(); 57 | int up = 1, down = 1; 58 | for (int i = 1; i < nums.size(); i++) { 59 | if (nums[i] > nums[i - 1]) 60 | // before this element what was the highest down + 1; 61 | up = down + 1; 62 | else if (nums[i] < nums[i - 1]) 63 | // before this element what was the highest up + 1; 64 | down = up + 1; 65 | } 66 | return max(up, down); 67 | } 68 | 69 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /BACKTRACKING/14_print_all_permutations_of_string.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/permutations-of-a-given-string2041/1 3 | 4 | sol: https://www.geeksforgeeks.org/write-a-c-program-to-print-all-permutations-of-a-given-string/ 5 | */ 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | /* 10 | here duplicate will also be included 11 | 12 | Time Complexity: 13 | O(n*n!) The time complexity is the same as the above approach, 14 | i.e. there are n! permutations and it requires O(n) time to print a permutation. 15 | */ 16 | 17 | // C++ program to print all 18 | // permutations with duplicates allowed 19 | #include 20 | using namespace std; 21 | 22 | 23 | // Function to print permutations of string 24 | // This function takes three parameters: 25 | // 1. String 26 | // 2. Starting index of the string 27 | // 3. Ending index of the string. 28 | void permute(string a, int l, int r) 29 | { 30 | // Base case 31 | if (l == r) 32 | cout << a << endl; 33 | else 34 | { 35 | // Permutations made 36 | for (int i = l; i <= r; i++) 37 | { 38 | 39 | // Swapping done 40 | swap(a[l], a[i]); 41 | 42 | // Recursion called 43 | permute(a, l + 1, r); 44 | 45 | //backtrack 46 | swap(a[l], a[i]); 47 | } 48 | } 49 | } 50 | 51 | // Driver Code 52 | int main() 53 | { 54 | string str = "ABC"; 55 | int n = str.size(); 56 | permute(str, 0, n - 1); 57 | return 0; 58 | } 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | // ----------------------------------------------------------------------------------------------------------------------- // 68 | /* 69 | by ignoring element every time 70 | (but here duplicate wont print) 71 | 72 | Time Complexity: 73 | O(n*n!) The time complexity is the same as the above approach, 74 | i.e. there are n! permutations and it requires O(n) time to print a permutation. 75 | */ 76 | #include 77 | #include 78 | using namespace std; 79 | 80 | void permute(string s, string answer) 81 | { 82 | if (s.length() == 0) 83 | { 84 | cout << answer << " "; 85 | return; 86 | } 87 | for (int i = 0; i < s.length(); i++) 88 | { 89 | char ch = s[i]; 90 | string left_substr = s.substr(0, i); 91 | string right_substr = s.substr(i + 1); 92 | string rest = left_substr + right_substr; 93 | permute(rest, answer + ch); 94 | } 95 | } 96 | 97 | int main() 98 | { 99 | string s; 100 | string answer = ""; 101 | 102 | cout << "Enter the string : "; 103 | cin >> s; 104 | 105 | cout << "\nAll possible strings are : "; 106 | permute(s, answer); 107 | return 0; 108 | } 109 | -------------------------------------------------------------------------------- /BACKTRACKING/19_kth_permutation_sequence_of_first_N_natural_no.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | sol: https://www.geeksforgeeks.org/find-the-k-th-permutation-sequence-of-first-n-natural-numbers/ 3 | 4 | link: https://leetcode.com/problems/permutation-sequence/ 5 | 6 | video: https://youtu.be/wT7gcXLYoao 7 | (watch the explanation) 8 | */ 9 | 10 | 11 | 12 | // ----------------------------------------------------------------------------------------------------------------------- // 13 | /* 14 | recursive solution 15 | 16 | TC: O(N!) + O(N logN) => O(N!) 17 | N! to generate every combination 18 | N logN to sort all the permutation 19 | 20 | SC: O(N) => as we keep deep copy of every combination 21 | */ 22 | 23 | set finalAns; 24 | void permute(string s, string answer) 25 | { 26 | if (s.length() == 0) 27 | { 28 | // cout << answer << endl; 29 | finalAns.insert(answer); 30 | return; 31 | } 32 | for (int i = 0; i < s.length(); i++) 33 | { 34 | char ch = s[i]; 35 | string left_substr = s.substr(0, i); 36 | string right_substr = s.substr(i + 1); 37 | string rest = left_substr + right_substr; 38 | permute(rest, answer + ch); 39 | } 40 | } 41 | string getPermutation(int n, int k) { 42 | string str = ""; 43 | for (int i = 1; i <= n; i++) { 44 | str += i + '0'; 45 | } 46 | 47 | permute(str, ""); 48 | 49 | int i = 0; 50 | 51 | for (auto curr : finalAns) { 52 | i++; 53 | if (i == k) return curr; 54 | } 55 | return ""; 56 | } 57 | 58 | 59 | 60 | 61 | 62 | // ----------------------------------------------------------------------------------------------------------------------- // 63 | /* 64 | efficient solution 65 | 66 | TC: O(N * N) => 1st for iterating to all no. and 2nd for erasing each time in each itertation 67 | SC: O(N) => for storing all no. 68 | */ 69 | class Solution { 70 | public: 71 | string getPermutation(int n, int k) { 72 | int fact = 1; 73 | vector numbers; 74 | for (int i = 1;i < n;i++) { 75 | fact = fact * i; 76 | numbers.push_back(i); 77 | } 78 | numbers.push_back(n); 79 | string ans = ""; 80 | 81 | k = k - 1; // as we will doing operation on 0th based indexing 82 | 83 | while (true) { 84 | ans = ans + to_string(numbers[k / fact]); 85 | numbers.erase(numbers.begin() + k / fact); 86 | 87 | // IMP 88 | if (numbers.size() == 0) { 89 | break; 90 | } 91 | 92 | // as we remove top unnecessary combination 93 | k = k % fact; 94 | 95 | // it also equal to fact /= size-1; each time 96 | fact = fact / numbers.size(); 97 | } 98 | return ans; 99 | } 100 | }; -------------------------------------------------------------------------------- /DP/11_egg_dropping_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/given_egg-dropping-puzzle-1587115620/1 3 | 4 | refer: DP_tut/MCM/5_egg... 5 | refer: aditya verma video 6 | 7 | variation of MCM 8 | */ 9 | 10 | // ----------------------------------------------------------------------------------------------------------------------- // 11 | 12 | // recursion 13 | int eggDrop(int given_egg, int given_floor) 14 | { 15 | // base condition 16 | if (given_floor == 0 || given_floor == 1 || given_egg == 1) return given_floor; 17 | 18 | // min attempts but in worst case 19 | int ans = INT_MAX - 1; 20 | 21 | // iterate through all the given_floor 22 | for (int k = 1;k <= given_floor;k++) { 23 | int temp = max(eggDrop(given_egg - 1, k - 1), eggDrop(given_egg, given_floor - k)); 24 | 25 | ans = min(temp, ans); 26 | } 27 | return ans; 28 | } 29 | 30 | // ----------------------------------------------------------------------------------------------------------------------- // 31 | 32 | // memoization (will give TLE) 33 | int memo[1001][1001]; 34 | int recur(int given_egg, int given_floor) { 35 | // base condition 36 | if (given_floor == 0 || given_floor == 1 || given_egg == 1) return given_floor; 37 | 38 | if (memo[given_egg][given_floor] != -1) return memo[given_egg][given_floor]; 39 | 40 | int ans = INT_MAX - 1; 41 | 42 | for (int k = 1;k <= given_floor;k++) { 43 | int temp = max(eggDrop(given_egg - 1, k - 1), eggDrop(given_egg, given_floor - k)); 44 | 45 | ans = min(temp, ans); 46 | } 47 | return memo[given_egg][given_floor] = ans; 48 | } 49 | 50 | int eggDrop(int given_egg, int given_floor) 51 | { 52 | memset(memo, -1, sizeof(memo)); 53 | recur(given_egg, given_floor); 54 | return memo[given_egg][given_floor]; 55 | } 56 | 57 | // ----------------------------------------------------------------------------------------------------------------------- // 58 | 59 | // optimized memoization 60 | int memo[1001][1001]; 61 | int recur(int given_egg, int given_floor) { 62 | 63 | if (given_floor == 0 || given_floor == 1 || given_egg == 1) return given_floor; 64 | 65 | if (memo[given_egg][given_floor] != -1) return memo[given_egg][given_floor]; 66 | 67 | 68 | int ans = INT_MAX - 1; 69 | 70 | 71 | for (int k = 1;k <= given_floor;k++) { 72 | int below = (memo[given_egg][given_floor] == -1) ? recur(given_egg - 1, k - 1) : memo[given_egg][given_floor]; 73 | int upper = (memo[given_egg][given_floor] == -1) ? recur(given_egg, given_floor - k) : memo[given_egg][given_floor]; 74 | /* why did we optimized? 75 | ans: here i guess we r saving stack memory 76 | */ 77 | 78 | int temp = 1 + max(below, upper); 79 | 80 | ans = min(ans, temp); 81 | } 82 | return memo[given_egg][given_floor] = ans; 83 | } 84 | int eggDrop(int given_egg, int given_floor) 85 | { 86 | memset(memo, -1, sizeof(memo)); 87 | return recur(given_egg, given_floor); 88 | } -------------------------------------------------------------------------------- /TRIE/05_implement_phone_directory.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/phone-directory4628/1# 3 | 4 | sol: https://www.geeksforgeeks.org/implement-a-phone-directory/ 5 | */ 6 | 7 | 8 | 9 | // ----------------------------------------------------------------------------------------------------------------------- // 10 | class Solution { 11 | public: 12 | struct TrieNode { 13 | unordered_map child; 14 | bool isLast; 15 | 16 | TrieNode() { 17 | for (char i = 'a'; i <= 'z'; i++) 18 | child[i] = NULL; 19 | 20 | isLast = false; 21 | } 22 | }; 23 | 24 | TrieNode* root = NULL; 25 | 26 | void insert(string s) 27 | { 28 | int len = s.length(); 29 | 30 | TrieNode* itr = root; 31 | for (int i = 0; i < len; i++) 32 | { 33 | TrieNode* nextNode = itr->child[s[i]]; 34 | if (nextNode == NULL) 35 | { 36 | nextNode = new TrieNode(); 37 | itr->child[s[i]] = nextNode; 38 | } 39 | 40 | itr = nextNode; 41 | 42 | if (i == len - 1) 43 | itr->isLast = true; 44 | } 45 | } 46 | 47 | void displayContactsUtil(TrieNode* curNode, string prefix, vector& v) 48 | { 49 | if (curNode->isLast) 50 | { 51 | v.push_back(prefix); 52 | } 53 | 54 | for (char i = 'a'; i <= 'z'; i++) 55 | { 56 | TrieNode* nextNode = curNode->child[i]; 57 | if (nextNode != NULL) 58 | displayContactsUtil(nextNode, prefix + (char)i, v); 59 | } 60 | } 61 | 62 | 63 | vector> displayContactsHelp(string str) 64 | { 65 | vector> ans; 66 | 67 | TrieNode* prevNode = root; 68 | 69 | string prefix = ""; 70 | int len = str.size(); 71 | 72 | int i; 73 | for (i = 0; i < len; i++) 74 | { 75 | prefix += (char)str[i]; 76 | 77 | char lastChar = prefix[i]; 78 | 79 | TrieNode* curNode = prevNode->child[lastChar]; 80 | 81 | if (curNode == NULL) break; 82 | 83 | vector v; 84 | 85 | displayContactsUtil(curNode, prefix, v); 86 | ans.push_back(v); 87 | 88 | prevNode = curNode; 89 | } 90 | 91 | for (; i < len; i++) 92 | { 93 | ans.push_back({ "0" }); 94 | } 95 | 96 | return ans; 97 | } 98 | 99 | void insertIntoTrie(string contacts[], int n) 100 | { 101 | root = new TrieNode(); 102 | 103 | for (int i = 0; i < n; i++) 104 | insert(contacts[i]); 105 | } 106 | 107 | vector> displayContacts(int n, string contact[], string s) 108 | { 109 | insertIntoTrie(contact, n); 110 | 111 | return displayContactsHelp(s); 112 | } 113 | }; -------------------------------------------------------------------------------- /BACKTRACKING/09_knights_tour_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/the-knights-tour-problem-backtracking-1/ 3 | */ 4 | 5 | 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | // C++ program for Knight Tour problem 10 | #include 11 | using namespace std; 12 | 13 | #define N 8 14 | 15 | int solveKTUtil(int x, int y, int movei, int sol[N][N], 16 | int xMove[], int yMove[]); 17 | 18 | /* A utility function to check if i,j are 19 | valid indexes for N*N chessboard */ 20 | int isSafe(int x, int y, int sol[N][N]) 21 | { 22 | return (x >= 0 && x < N&& y >= 0 && y < N 23 | && sol[x][y] == -1); 24 | } 25 | 26 | /* A utility function to print 27 | solution matrix sol[N][N] */ 28 | void printSolution(int sol[N][N]) 29 | { 30 | for (int x = 0; x < N; x++) { 31 | for (int y = 0; y < N; y++) 32 | cout << " " << setw(2) << sol[x][y] << " "; 33 | cout << endl; 34 | } 35 | } 36 | 37 | /* This function solves the Knight Tour problem using 38 | Backtracking. This function mainly uses solveKTUtil() 39 | to solve the problem. It returns false if no complete 40 | tour is possible, otherwise return true and prints the 41 | tour. 42 | Please note that there may be more than one solutions, 43 | this function prints one of the feasible solutions. */ 44 | int solveKT() 45 | { 46 | int sol[N][N]; 47 | 48 | /* Initialization of solution matrix */ 49 | for (int x = 0; x < N; x++) 50 | for (int y = 0; y < N; y++) 51 | sol[x][y] = -1; 52 | 53 | /* xMove[] and yMove[] define next move of Knight. 54 | xMove[] is for next value of x coordinate 55 | yMove[] is for next value of y coordinate */ 56 | int xMove[8] = { 2, 1, -1, -2, -2, -1, 1, 2 }; 57 | int yMove[8] = { 1, 2, 2, 1, -1, -2, -2, -1 }; 58 | 59 | // Since the Knight is initially at the first block 60 | sol[0][0] = 0; 61 | 62 | /* Start from 0,0 and explore all tours using 63 | solveKTUtil() */ 64 | if (solveKTUtil(0, 0, 1, sol, xMove, yMove) == 0) { 65 | cout << "Solution does not exist"; 66 | return 0; 67 | } 68 | else 69 | printSolution(sol); 70 | 71 | return 1; 72 | } 73 | 74 | /* A recursive utility function to solve Knight Tour 75 | problem */ 76 | int solveKTUtil(int x, int y, int movei, int sol[N][N], 77 | int xMove[N], int yMove[N]) 78 | { 79 | int k, next_x, next_y; 80 | if (movei == N * N) 81 | return 1; 82 | 83 | /* Try all next moves from 84 | the current coordinate x, y */ 85 | for (k = 0; k < 8; k++) { 86 | next_x = x + xMove[k]; 87 | next_y = y + yMove[k]; 88 | if (isSafe(next_x, next_y, sol)) { 89 | sol[next_x][next_y] = movei; 90 | if (solveKTUtil(next_x, next_y, movei + 1, sol, 91 | xMove, yMove) 92 | == 1) 93 | return 1; 94 | else 95 | 96 | // backtracking 97 | sol[next_x][next_y] = -1; 98 | } 99 | } 100 | return 0; 101 | } 102 | 103 | // Driver Code 104 | int main() 105 | { 106 | // Function Call 107 | solveKT(); 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /DP/15_gold_mine.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/gold-mine-problem/ 3 | */ 4 | 5 | 6 | 7 | #include 8 | using namespace std; 9 | const int MAX = 100; 10 | 11 | // ----------------------------------------------------------------------------------------------------------------------- // 12 | 13 | // memoization 14 | int dp[1001][1001]; 15 | int recur(int gold[][MAX], int x, int y, int m, int n) { 16 | if (x < 0 || y < 0 || x >= m || y >= n) return 0; 17 | 18 | 19 | return gold[x][y] + max({ recur(gold, x + 1, y + 1, m, n), recur(gold, x, y + 1, m, n), recur(gold, x - 1, y + 1, m, n) }); 20 | } 21 | int getMaxGold(int gold[][MAX], int m, int n) { 22 | int ans = INT_MIN; 23 | for (int i = 0;i < m;i++) { 24 | ans = max(ans, recur(gold, i, 0, m, n)); 25 | } 26 | return ans; 27 | } 28 | 29 | // ----------------------------------------------------------------------------------------------------------------------- // 30 | 31 | // tabulation 32 | const int MAX = 100; 33 | 34 | // Returns maximum amount of gold that can be collected 35 | // when journey started from first column and moves 36 | // allowed are right, right-up and right-down 37 | int getMaxGold(int gold[][MAX], int m, int n) 38 | { 39 | // Create a table for storing intermediate results 40 | // and initialize all cells to 0. The first row of 41 | // goldMineTable gives the maximum gold that the miner 42 | // can collect when starts that row 43 | int goldTable[m][n]; 44 | memset(goldTable, 0, sizeof(goldTable)); 45 | 46 | for (int col = n - 1; col >= 0; col--) 47 | { 48 | for (int row = 0; row < m; row++) 49 | { 50 | // Gold collected on going to the cell on the right(->) 51 | int right = (col == n - 1) ? 0 : goldTable[row][col + 1]; 52 | 53 | // Gold collected on going to the cell to right up (/) 54 | int right_up = (row == 0 || col == n - 1) ? 0 : 55 | goldTable[row - 1][col + 1]; 56 | 57 | // Gold collected on going to the cell to right down (\) 58 | int right_down = (row == m - 1 || col == n - 1) ? 0 : 59 | goldTable[row + 1][col + 1]; 60 | 61 | // Max gold collected from taking either of the 62 | // above 3 paths 63 | goldTable[row][col] = gold[row][col] + 64 | max(right, max(right_up, right_down)); 65 | 66 | } 67 | } 68 | 69 | // The max amount of gold collected will be the max 70 | // value in first column of all rows 71 | int res = goldTable[0][0]; 72 | for (int i = 1; i < m; i++) 73 | res = max(res, goldTable[i][0]); 74 | return res; 75 | } 76 | 77 | 78 | // Driver Code 79 | int main() 80 | { 81 | int gold[MAX][MAX] = { {1, 3, 1, 5}, 82 | {2, 2, 4, 1}, 83 | {5, 0, 2, 3}, 84 | {0, 6, 1, 2} 85 | }; 86 | int m = 4, n = 4; 87 | return getMaxGold(gold, m, n); 88 | return 0; 89 | } 90 | 91 | // ----------------------------------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------- /GREEDY/18_maximum_sum_of_absolute_difference_of_an_array.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/maximum-sum-absolute-difference-array/ 3 | */ 4 | 5 | 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | /* 10 | using vector 11 | TC: O(N logN) 12 | SC: O(N) 13 | */ 14 | // CPP implementation of 15 | // above algorithm 16 | #include 17 | using namespace std; 18 | 19 | int MaxSumDifference(int a[], int n) 20 | { 21 | // final sequence stored in the vector 22 | vector finalSequence; 23 | 24 | // sort the original array 25 | // so that we can retrieve 26 | // the large elements from 27 | // the end of array elements 28 | sort(a, a + n); 29 | 30 | // In this loop first we will insert 31 | // one smallest element not entered 32 | // till that time in final sequence 33 | // and then enter a highest element 34 | // (not entered till that time) in 35 | // final sequence so that we 36 | // have large difference value. This 37 | // process is repeated till all array 38 | // has completely entered in sequence. 39 | // Here, we have loop till n/2 because 40 | // we are inserting two elements at a 41 | // time in loop. 42 | for (int i = 0; i < n / 2; ++i) { 43 | finalSequence.push_back(a[i]); 44 | finalSequence.push_back(a[n - i - 1]); 45 | } 46 | 47 | // If there are odd elements, push the 48 | // middle element at the end. 49 | if (n % 2 != 0) 50 | finalSequence.push_back(a[n / 2]); 51 | 52 | // variable to store the 53 | // maximum sum of absolute 54 | // difference 55 | int MaximumSum = 0; 56 | 57 | // In this loop absolute difference 58 | // of elements for the final sequence 59 | // is calculated. 60 | for (int i = 0; i < n - 1; ++i) { 61 | MaximumSum = MaximumSum + abs(finalSequence[i] - 62 | finalSequence[i + 1]); 63 | } 64 | 65 | // absolute difference of last element 66 | // and 1st element 67 | MaximumSum = MaximumSum + abs(finalSequence[n - 1] - 68 | finalSequence[0]); 69 | 70 | // return the value 71 | return MaximumSum; 72 | } 73 | 74 | // Driver function 75 | int main() 76 | { 77 | int a[] = { 1, 2, 4, 8 }; 78 | int n = sizeof(a) / sizeof(a[0]); 79 | 80 | cout << MaxSumDifference(a, n) << endl; 81 | } 82 | 83 | 84 | 85 | 86 | 87 | // ----------------------------------------------------------------------------------------------------------------------- // 88 | /* 89 | more efficient 90 | TC: O(N logN) 91 | SC: O(1) 92 | */ 93 | int MaxSumDifference(int a[], int n) { 94 | sort(a, a + n); 95 | 96 | int ans = 0; 97 | 98 | /* 99 | if odd let's say n=7 then 7/2 = 3, till 2 in for loop. 100 | if even let's say n=8 then 8/2 = 4, till 3 in for loop. 101 | */ 102 | for (int i = 0; i < n / 2; i++) { 103 | int diff = abs(a[i] - a[n - 1 - i]); 104 | 105 | // as if we have ran all for loop all diff would have repeated hence double it everytime, 106 | // while middle ele. would have abs value 0. 107 | ans += diff * 2; 108 | } 109 | return ans; 110 | } 111 | -------------------------------------------------------------------------------- /Greedy/18_maximum_sum_of_absolute_difference_of_an_array.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://www.geeksforgeeks.org/maximum-sum-absolute-difference-array/ 3 | */ 4 | 5 | 6 | 7 | 8 | // ----------------------------------------------------------------------------------------------------------------------- // 9 | /* 10 | using vector 11 | TC: O(N logN) 12 | SC: O(N) 13 | */ 14 | // CPP implementation of 15 | // above algorithm 16 | #include 17 | using namespace std; 18 | 19 | int MaxSumDifference(int a[], int n) 20 | { 21 | // final sequence stored in the vector 22 | vector finalSequence; 23 | 24 | // sort the original array 25 | // so that we can retrieve 26 | // the large elements from 27 | // the end of array elements 28 | sort(a, a + n); 29 | 30 | // In this loop first we will insert 31 | // one smallest element not entered 32 | // till that time in final sequence 33 | // and then enter a highest element 34 | // (not entered till that time) in 35 | // final sequence so that we 36 | // have large difference value. This 37 | // process is repeated till all array 38 | // has completely entered in sequence. 39 | // Here, we have loop till n/2 because 40 | // we are inserting two elements at a 41 | // time in loop. 42 | for (int i = 0; i < n / 2; ++i) { 43 | finalSequence.push_back(a[i]); 44 | finalSequence.push_back(a[n - i - 1]); 45 | } 46 | 47 | // If there are odd elements, push the 48 | // middle element at the end. 49 | if (n % 2 != 0) 50 | finalSequence.push_back(a[n / 2]); 51 | 52 | // variable to store the 53 | // maximum sum of absolute 54 | // difference 55 | int MaximumSum = 0; 56 | 57 | // In this loop absolute difference 58 | // of elements for the final sequence 59 | // is calculated. 60 | for (int i = 0; i < n - 1; ++i) { 61 | MaximumSum = MaximumSum + abs(finalSequence[i] - 62 | finalSequence[i + 1]); 63 | } 64 | 65 | // absolute difference of last element 66 | // and 1st element 67 | MaximumSum = MaximumSum + abs(finalSequence[n - 1] - 68 | finalSequence[0]); 69 | 70 | // return the value 71 | return MaximumSum; 72 | } 73 | 74 | // Driver function 75 | int main() 76 | { 77 | int a[] = { 1, 2, 4, 8 }; 78 | int n = sizeof(a) / sizeof(a[0]); 79 | 80 | cout << MaxSumDifference(a, n) << endl; 81 | } 82 | 83 | 84 | 85 | 86 | 87 | // ----------------------------------------------------------------------------------------------------------------------- // 88 | /* 89 | more efficient 90 | TC: O(N logN) 91 | SC: O(1) 92 | */ 93 | int MaxSumDifference(int a[], int n) { 94 | sort(a, a + n); 95 | 96 | int ans = 0; 97 | 98 | /* 99 | if odd let's say n=7 then 7/2 = 3, till 2 in for loop. 100 | if even let's say n=8 then 8/2 = 4, till 3 in for loop. 101 | */ 102 | for (int i = 0; i < n / 2; i++) { 103 | int diff = abs(a[i] - a[n - 1 - i]); 104 | 105 | // as if we have ran all for loop all diff would have repeated hence double it everytime, 106 | // while middle ele. would have abs value 0. 107 | ans += diff * 2; 108 | } 109 | return ans; 110 | } 111 | -------------------------------------------------------------------------------- /GREEDY/04_water_connection_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | link: https://practice.geeksforgeeks.org/problems/water-connection-problem5822/1 3 | 4 | sol: https://www.geeksforgeeks.org/water-connection-problem/ 5 | */ 6 | 7 | 8 | 9 | 10 | // ----------------------------------------------------------------------------------------------------------------------- // 11 | /* 12 | using DFS 13 | */ 14 | 15 | // number of houses and number 16 | // of pipes 17 | int n, p; 18 | 19 | // Array rd stores the 20 | // ending vertex of pipe 21 | int rd[1100]; 22 | 23 | // Array wd stores the value 24 | // of diameters between two pipes 25 | int wt[1100]; 26 | 27 | // Array cd stores the 28 | // starting end of pipe 29 | int cd[1100]; 30 | 31 | vector> ans; 32 | 33 | int mn; 34 | 35 | int dfs(int w) 36 | { 37 | if (cd[w] == 0) 38 | return w; 39 | if (wt[w] < mn) 40 | mn = wt[w]; 41 | return dfs(cd[w]); 42 | } 43 | 44 | // Function performing calculations. 45 | vector> solve(int arr[][3]) 46 | { 47 | int i = 0; 48 | 49 | while (i < p) { 50 | 51 | int q = arr[i][0], h = arr[i][1], 52 | t = arr[i][2]; 53 | 54 | cd[q] = h; 55 | wt[q] = t; 56 | rd[h] = q; 57 | i++; 58 | } 59 | 60 | ans.clear(); 61 | 62 | for (int j = 1; j <= n; ++j) 63 | 64 | /*If a pipe has no ending vertex 65 | but has starting vertex i.e is 66 | an outgoing pipe then we need 67 | to start DFS with this vertex.*/ 68 | if (rd[j] == 0 && cd[j]) { 69 | mn = 1000000000; 70 | int w = dfs(j); 71 | 72 | // We put the details of component 73 | // in final output array 74 | ans.push_back({ j, w, mn }); 75 | } 76 | return ans; 77 | } 78 | 79 | vector> solve(int mainN, int mainP, vector a, vector b, vector d) 80 | { 81 | n = mainN; 82 | p = mainP; 83 | 84 | memset(rd, 0, sizeof(rd)); 85 | memset(cd, 0, sizeof(cd)); 86 | memset(wt, 0, sizeof(wt)); 87 | 88 | int arr[p][3]; 89 | 90 | for (int i = 0;i < p;i++) { 91 | arr[i][0] = a[i]; 92 | arr[i][1] = b[i]; 93 | arr[i][2] = d[i]; 94 | } 95 | return solve(arr); 96 | } 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | // ----------------------------------------------------------------------------------------------------------------------- // 106 | // logic is correct but TLE (so just go through the logic) 107 | vector> solve(int n, int p, vector a, vector b, vector d) 108 | { 109 | vector> ans; 110 | map> m; 111 | 112 | for (int i = 0;i < p;i++) { 113 | m[a[i]] = { b[i], d[i] }; 114 | } 115 | 116 | for (int i = 0;i < p;i++) { 117 | if (m.count(m[a[i]].first) <= 0) continue; 118 | 119 | int curr = m[a[i]].first; 120 | while (m.count(curr) > 0) { 121 | m[a[i]].first = m[curr].first; 122 | m[a[i]].second = min(m[a[i]].second, m[curr].second); 123 | m[curr].second = INT_MAX; 124 | 125 | 126 | curr = m[curr].first; 127 | 128 | } 129 | } 130 | for (auto i = m.begin();i != m.end();i++) { 131 | if ((i->second).second != INT_MAX) ans.push_back({ i->first, (i->second).first, (i->second).second }); 132 | } 133 | return ans; 134 | } --------------------------------------------------------------------------------