├── .gitignore ├── EPI_prep ├── assets │ ├── add_two_linkedlist.png │ ├── after_cyclic_shift.png │ ├── before_cyclic_shift.png │ ├── bst.png │ ├── bst_min_height.png │ ├── doubly_linkedlist.png │ ├── even_odd_merge.png │ ├── graph_undirected.png │ ├── graph_with_weights.png │ ├── graphs_dag.png │ ├── inc_dec_array.png │ ├── list_pivoting.png │ ├── max_heap.png │ ├── max_heap_delete.png │ ├── merge_two_lists.png │ ├── overlapping_lists.png │ ├── overlapping_lists_with_cycle.png │ ├── remove_dups_from_sorted_list.png │ ├── right_sibling.png │ ├── singly_linkedlist.png │ └── symmetric_binary_tree.png └── src │ ├── binary_search_trees │ ├── 0_search_bst │ │ ├── README.md │ │ └── search_bst.py │ ├── 10_range_look_up_problem │ │ ├── README.md │ │ └── range_lookup.py │ ├── 11_add_credits │ │ ├── README.md │ │ └── add_credits.py │ ├── 1_check_if_bst_satisfies_bst_property │ │ ├── README.md │ │ ├── is_bst.py │ │ └── is_bst_2.py │ ├── 2_find_first_key_greater_than_a_value_in_bst │ │ ├── README.md │ │ └── find_first_greater_than_k.py │ ├── 3_k_largest_in_bst │ │ ├── README.md │ │ ├── k_largest_1.py │ │ ├── k_largest_2.py │ │ └── k_largest_3.py │ ├── 4_lca_in_a_bst │ │ ├── README.md │ │ └── find_lca.py │ ├── 5.1_reconstruct_bst_from_post_order_traversal_data │ │ ├── README.md │ │ └── reconstruct_bst.py │ ├── 5_reconstruct_bst_from_preorder_traversal_data │ │ ├── README.md │ │ └── reconstruct_bst.py │ ├── 6_closest_entries_in_3_sorted_arrays │ │ ├── README.md │ │ └── close_entries.py │ ├── 7_enumerate_numbers_of_the_form_a+b_sqrt2 │ │ ├── README.md │ │ ├── enumerate_numbers.py │ │ └── enumerate_numbers_1.py │ ├── 8_build_minimum_height_bst │ │ ├── README.md │ │ ├── min_height_bst.py │ │ └── min_height_bst_2.py │ ├── 9_ordered_bst_nodes │ │ ├── README.md │ │ └── is_bst_ordered.py │ └── README.md │ ├── binary_trees │ ├── 0_binary_tree_traversal │ │ └── tree_traversals.py │ ├── 10_compute_sucessor │ │ ├── README.md │ │ └── compute_succesor.py │ ├── 11.1_preorder_traversal_in_constant_space │ │ ├── README.md │ │ └── preorder_traversal.py │ ├── 11.2_postorder_traversal_in_constant_space │ │ ├── README.md │ │ └── postorder_traversal.py │ ├── 11_inorder_traversal_in_constant_space │ │ ├── README.md │ │ └── inorder_traversal.py │ ├── 12_reconstruct_binary_tree_from_preorder_inorder_traversal │ │ ├── README.md │ │ └── reconstruct_bt.py │ ├── 13_reconstruct_bt_from_preorder_traversal │ │ ├── README.md │ │ ├── reconstruct_bt_1.py │ │ └── reconstruct_bt_2.py │ ├── 14_form_a_linkedlist_from_leaves_of_bt │ │ ├── README.md │ │ ├── create_list_2.py │ │ └── create_list_of_leaves.py │ ├── 15_compute_exterior_of_binary_tree │ │ ├── README.md │ │ └── exterior_bt.py │ ├── 16_compute_right_sibling_tree │ │ ├── README.md │ │ └── compute_right_sibling_tree.py │ ├── 1_is_binary_tree_height_balanced │ │ ├── README.md │ │ └── balanced_binary_tree.py │ ├── 2_is_binary_tree_symmetric │ │ ├── README.md │ │ └── is_symetric.py │ ├── 3_lca │ │ ├── README.md │ │ └── lca.py │ ├── 4_lca_with_parent_pointers │ │ ├── README.md │ │ └── lca.py │ ├── 5_sum_root_to_leaf │ │ ├── README.md │ │ └── sum_root_to_leaf.py │ ├── 6.1_root_to_leaf_sum_all_paths │ │ ├── README.md │ │ └── all_paths.py │ ├── 6_root_leaf_path_with_specified_sum │ │ ├── README.md │ │ └── has_path_sum.py │ ├── 7_inorder_traversal_without_recursion │ │ ├── README.md │ │ └── inorder_traversal.py │ ├── 8_preorder_traversal_without_recursion │ │ ├── README.md │ │ └── preorder_traversal.py │ ├── 9.1_kth_node_in_inorder_traversal │ │ ├── README.md │ │ └── kth_node.py │ ├── 9_kth_node_in_inorder_traversal │ │ ├── README.md │ │ └── kth_node.py │ └── README.md │ ├── graphs │ ├── 1_search_maze │ │ ├── README.md │ │ └── search_maze.py │ └── README.md │ ├── heaps │ ├── 1_merge_sorted_arrays │ │ ├── README.md │ │ └── merge_sorted_arrays.py │ ├── 2_sort_increasing_decreasing_array │ │ ├── README.md │ │ └── sort_k_inc_dec_array.py │ ├── 3_sort_almost_sorted_array │ │ ├── README.md │ │ └── sort_approximately_sorted_array.py │ ├── 4_compute_k_closest_stars │ │ ├── README.md │ │ └── k_closest_stars.py │ ├── 5_compute_median_from_a_stream │ │ ├── README.md │ │ └── compute_median.py │ ├── 6_k_largest_elements_in_a_heap │ │ ├── README.md │ │ ├── k_largest_elements.py │ │ └── k_largest_elements_1.py │ └── README.md │ ├── linkedlist │ ├── 1.1_merge_two_sorted_doubly_linkedlist │ │ ├── README.md │ │ └── merge_list.py │ ├── 10_even_odd_merge │ │ ├── README.md │ │ └── even_odd_merge.py │ ├── 11_palindromic_linkedlist │ │ ├── README.md │ │ └── is_palindrome.py │ ├── 12_implement_list_pivoting │ │ ├── README.md │ │ └── list_pivoting.py │ ├── 13_add_two_linkedlists │ │ ├── README.md │ │ └── add_lists.py │ ├── 1_merge_two_sorted_lists │ │ ├── README.md │ │ └── merge_two_list.py │ ├── 2.1_reverse_singly_linkedlist │ │ ├── README.md │ │ └── reverse_singly_linkedlist.py │ ├── 2.2_reverse_every_k_sublist │ │ └── reverse_k_sublist.py │ ├── 2_reverse_a_single_sublist │ │ ├── README.md │ │ ├── reverse_sublist_1.py │ │ └── reverse_sublist_2.py │ ├── 3.1_start_of_linkedlist_cycle │ │ ├── find_cycle_start_1.py │ │ └── find_cycle_start_2.py │ ├── 3_test_for_cyclicity │ │ ├── README.md │ │ └── has_cycle.py │ ├── 4_test_for_overlapping_lists │ │ ├── README.md │ │ └── has_overlapping_list.py │ ├── 5_test_for_overlapping_lists_with_cycles │ │ ├── README.md │ │ └── has_overlapping_list.py │ ├── 6_delete_node_from_singly_linkedlist │ │ ├── README.md │ │ └── delete_node.py │ ├── 7_remove_kth_last_element_from_list │ │ ├── README.md │ │ └── remove_kth_last_element.py │ ├── 8_remove_duplicates_from_sorted_list │ │ ├── README.md │ │ └── remove_duplicates.py │ ├── 9_cyclic_right_shift_of_singly_linkedlist │ │ ├── README.md │ │ └── cyclic_right_shift_list.py │ └── README.md │ └── recursion │ ├── 0_greatest_common_divisor │ └── gcd.py │ ├── 1_towers_of_hanoi │ └── towers_of_hanoi.py │ ├── 3_permutations │ └── permutations.py │ ├── 4_power_set │ └── power_set.py │ ├── 5_subset_of_size_k │ ├── README.md │ └── combinations.py │ ├── 6_generate_balanced_parentheses │ ├── README.md │ └── generate_balanced_parentheses.py │ ├── 7_generate_palindromic_decompositions │ └── palindromic_decompositions.py │ ├── 8_generate_binary_trees │ └── generate_binary_trees.py │ ├── 9_solve_sodoku │ └── solve_sudoku.py │ └── README.md ├── README.md ├── algorithms ├── assets │ └── kruskals_sorted.png └── src │ ├── general_algorithms │ └── kadanes_algorithm.py │ ├── graph_algorithms │ ├── bellman_ford_algorithm │ │ ├── README.md │ │ └── bellman_ford_algorithm.py │ ├── bfs │ │ ├── README.md │ │ └── breath_first_search.py │ ├── dfs │ │ ├── README.md │ │ └── depth_first_search.py │ ├── dijkstras_algorithm │ │ ├── README.md │ │ ├── dijkstras_algorithm_with_min_heap.py │ │ └── dijkstras_algorithm_with_sorted_set.py │ ├── floyd_warshall_algorithm │ │ ├── README.md │ │ └── floyd_warshall_algorithm.py │ ├── kosarajus_algorithm │ │ ├── README.md │ │ └── kosarajus_algorithm.py │ ├── minimum_spanning_trees │ │ ├── README.md │ │ ├── kruskals_algorithm │ │ │ ├── README.md │ │ │ └── krusals_algorithm.py │ │ └── prims_algorithm │ │ │ ├── README.md │ │ │ ├── prims.py │ │ │ └── prims_2.py │ ├── single_source_shortest_path_problem │ │ ├── dijkstras_algorithm_sssp.py │ │ └── sss_path_bfs.py │ └── topological_sort │ │ ├── README.md │ │ ├── topological_sort_bfs.py │ │ └── topological_sort_recursion.py │ └── sorting_algorithms │ ├── README.md │ ├── bubble_sort.py │ ├── insertion_sort.py │ ├── merge_sort.py │ ├── quick_sort.py │ └── selection_sort.py ├── assets └── big-o-graph.png ├── bit_manipulation ├── left_shift_operator.py └── right_shift_operator.py ├── blind_75 └── src │ ├── arrays │ ├── buy_and_sell_stock │ │ ├── README.md │ │ └── buy_and_sell_stock.py │ ├── contains_duplicate │ │ ├── README.md │ │ └── contains_duplicate.py │ ├── maximum_subarray │ │ └── README.md │ ├── product_of_array_except_self │ │ ├── README.md │ │ └── product_of_array_except_self.py │ └── two_sum │ │ ├── README.md │ │ └── two_sum.py │ ├── linkedlists │ ├── README.md │ ├── lc_141_linkedlist_cycle │ │ ├── README.md │ │ └── linkedlist_cycle.py │ ├── lc_143_reorder_list │ │ ├── README.md │ │ └── reorder_list.py │ ├── lc_19_remove_nth_node_from_list │ │ ├── README.md │ │ └── remove_nth_node_from_list.py │ ├── lc_206_reverse_linkedlist │ │ ├── README.md │ │ └── reverse_linkedlist.py │ ├── lc_21_merge_two_sorted_lists │ │ ├── README.md │ │ └── merge_two_sorted_lists.py │ └── lc_23_merge_k_sorted_lists │ │ ├── README.md │ │ └── merge_k_sorted_lists.py │ └── trees │ ├── README.md │ ├── lc_100_same_tree │ ├── README.md │ └── same_tree.py │ ├── lc_102_binary_tree_level_order_traversal │ ├── README.md │ └── binary_tree_level_order_traversal.py │ ├── lc_104_max_depth_of_binary_tree │ ├── README.md │ └── max_depth_of_binary_tree.py │ ├── lc_105_construct_binary_tree_from_preorder_inorder_traversal │ ├── README.md │ └── construct_binary_tree_from_preorder_inorder_traversal.py │ ├── lc_124_binary_tree_maximum_path_sum │ ├── README.md │ └── binary_tree_maximum_path_sum.py │ ├── lc_226_invert_binary_tree │ ├── README.md │ └── invert_binary_tree.py │ ├── lc_230_kth_smallest_in_bst │ ├── README.md │ └── kth_smallest_in_bst.py │ ├── lc_235_lca_of_binary_search_tree │ ├── README.md │ └── lca_bst.py │ ├── lc_297_serialize_and_deserialize_binary_tree │ ├── README.md │ └── serialize_and_deserialize_binary_tree.py │ ├── lc_572_subtree_of_another_tree │ ├── README.md │ └── subtree_of_another_tree.py │ └── lc_98_validate_binary_search_tree │ ├── README.md │ └── validate_binary_search_tree.py ├── data-structures ├── assets │ ├── array-representation.jpeg │ ├── circular_doubly_linkedlist.png │ ├── circular_linkedlist.png │ ├── circular_queue.png │ ├── collision-resolution.jpeg │ ├── doubly-linked-list.jpeg │ ├── doubly_linkedlist.png │ ├── graph.jpeg │ ├── hash-table.jpeg │ ├── linked-list.jpeg │ ├── linkedList_array_comparisons.png │ ├── linkedlist.png │ ├── max-heap.jpeg │ ├── min-heap.jpeg │ ├── queue.jpeg │ ├── queue_comparisons.png │ ├── queue_linkedlist.png │ ├── queue_with_list.png │ ├── stack_linkedlist.png │ ├── stack_list.png │ ├── time_complexity_linkedList.png │ └── trie.jpeg └── src │ ├── circular-doubly-linked-list │ ├── README.md │ └── circular_doubly_linked_list.py │ ├── circular-linked-list │ ├── README.md │ └── circular_linked_list.py │ ├── disjoint-sets │ └── disjoint_set.py │ ├── doubly-linked-list │ ├── README.md │ └── doubly_linked_list.py │ ├── graph │ ├── README.md │ └── graph.py │ ├── hashtable │ └── README.md │ ├── heap │ ├── README.md │ └── binary_heap.py │ ├── linked-list │ ├── README.md │ └── linked_list.py │ ├── priority_queue │ └── README.md │ ├── queue │ ├── README.md │ ├── circular_queue │ │ ├── README.md │ │ └── queue.py │ ├── queue_using_librarys │ │ ├── Deque.py │ │ ├── MultiprocessingQueue.py │ │ └── QueueModule.py │ ├── queue_with_linkedlist │ │ ├── README.md │ │ └── queue.py │ └── queue_with_list │ │ ├── README.md │ │ └── queue.py │ ├── stack │ ├── README.md │ ├── stack_with_limited_list.py │ ├── stack_with_linkedlist.py │ └── stack_with_list.py │ ├── tree │ ├── README.md │ ├── avl-tree │ │ ├── README.md │ │ ├── avl_tree.py │ │ └── queue.py │ ├── binary-search-tree │ │ ├── README.md │ │ ├── binary_search_tree.py │ │ └── queue.py │ └── binary-tree │ │ ├── binary-tree-with-linkedlist │ │ ├── binary_tree.py │ │ └── queue.py │ │ └── binary-tree-with-list │ │ └── binary_tree.py │ └── trie │ └── README.md ├── leetcode └── src │ ├── array&hashing │ ├── README.md │ ├── lc_152_max_product_subarray │ │ ├── README.md │ │ ├── max_product_brute_force.py │ │ └── max_product_subarray.py │ ├── lc_1_two_sum │ │ ├── README.md │ │ └── two_sum.py │ ├── lc_217_contains_duplicate │ │ ├── README.md │ │ └── contains_duplicate.py │ ├── lc_238_product_of_array_except_itself │ │ ├── README.md │ │ └── product_of_array.py │ ├── lc_242_valid_anagram │ │ ├── README.md │ │ └── valid_anagram.py │ └── lc_347_top_k_frequent_elements │ │ ├── README.md │ │ └── top_k.py │ ├── backtracking │ ├── README.md │ ├── lc_115_distinct_subsequences │ │ ├── README.md │ │ └── distinct_subs.py │ ├── lc_131_palindrom_partitioning │ │ ├── README.md │ │ └── palindrome_partition.py │ ├── lc_39_combination_sum_I │ │ ├── README.md │ │ └── combination_sum.py │ ├── lc_40_combination_sum_II │ │ ├── README.md │ │ └── combination_sum.py │ ├── lc_784_letter_code_permutation │ │ ├── README.md │ │ └── letter_code_permutation.py │ ├── lc_78_subsets │ │ ├── README.md │ │ └── subsets.py │ └── lc_90_subsets_II │ │ ├── README.md │ │ └── subsets.py │ ├── binary_trees │ ├── README.md │ ├── bottom_view_of_binary_tree │ │ ├── README.md │ │ └── bottom_view.py │ ├── lc_1008_construct_binary_tree_from_preorder_traversal │ │ ├── README.md │ │ └── construct_binary_tree_from_preorder_traversal.py │ ├── lc_100_same_tree │ │ ├── README.md │ │ └── same_tree.py │ ├── lc_101_symmetric_tree │ │ ├── README.md │ │ └── symmetric_tree.py │ ├── lc_102_binary_tree_level_order_traversal │ │ ├── README.md │ │ └── binary_tree_level_order_traversal.py │ ├── lc_103_binary_tree_zigzag_level_order_traversal │ │ ├── README.md │ │ └── binary_tree_zigzag_level_order_traversal.py │ ├── lc_104_max_depth_of_binary_tree │ │ ├── README.md │ │ └── max_depth_of_binary_tree.py │ ├── lc_105_construct_binary_tree_from_preorder_inorder_traversal │ │ ├── README.md │ │ └── construct_binary_tree_from_preorder_inorder_traversal.py │ ├── lc_106_construct_binary_tree_from_inorder_postorder_traversal │ │ ├── README.md │ │ └── construct_binary_tree_from_inorder_postorder_traversal.py │ ├── lc_107_binary_tree_level_order_traversal_II │ │ ├── README.md │ │ └── binary_tree_level_order_traversal.py │ ├── lc_108_converted_sorted_array_to_bst │ │ ├── README.md │ │ └── converted_sorted_array_to_bst.py │ ├── lc_110_balanced_binary_tree │ │ ├── README.md │ │ └── balanced_binary_tree.py │ ├── lc_111_min_depth_of_binary_tree │ │ ├── README.md │ │ └── min_depth_of_binary_tree.py │ ├── lc_112_path_sum │ │ ├── README.md │ │ └── path_sum.py │ ├── lc_113_path_sum_II │ │ ├── README.md │ │ └── path_sum.py │ ├── lc_114_flatten_binary_tree_to_linkedlist │ │ ├── README.md │ │ └── flatten_binary_tree_to_linkedlist.py │ ├── lc_116_populate_next_right_pointers_in_each_node │ │ ├── README.md │ │ └── populate_next_right_pointers.py │ ├── lc_117_populate_next_right_pointer_in_each_node_II │ │ ├── README.md │ │ └── populate_next_right_pointers.py │ ├── lc_124_binary_tree_maximum_path_sum │ │ ├── README.md │ │ └── binary_tree_maximum_path_sum.py │ ├── lc_129_sum_root_to_leaf_numbers │ │ ├── README.md │ │ └── sum_root_to_leaf_numbers.py │ ├── lc_144_preorder_traversal │ │ ├── README.md │ │ ├── preorder_iterative.py │ │ └── preorder_traversal.py │ ├── lc_145_postorder_traversal │ │ ├── README.md │ │ ├── post_order_iterative.py │ │ └── post_traversal.py │ ├── lc_173_binary_search_tree_iterator │ │ ├── README.md │ │ └── binary_search_tree_iterator.py │ ├── lc_199_binary_tree_right_side_view │ │ ├── README.md │ │ └── binary_tree_right_side_view.py │ ├── lc_222_count_complete_tree_nodes │ │ ├── README.md │ │ └── count_complete_tree_nodes.py │ ├── lc_226_invert_binary_tree │ │ ├── README.md │ │ └── invert_binary_tree.py │ ├── lc_230_kth_smallest_in_bst │ │ ├── README.md │ │ └── kth_smallest_in_bst.py │ ├── lc_235_lca_of_binary_search_tree │ │ ├── README.md │ │ └── lca_bst.py │ ├── lc_236_lowest_common_ancestor_of_binary_tree │ │ ├── README.md │ │ └── lowest_common_ancestor_of_binary_tree.py │ ├── lc_257_binary_tree_paths │ │ ├── README.md │ │ └── binary_tree_paths.py │ ├── lc_297_serialize_and_deserialize_binary_tree │ │ ├── README.md │ │ └── serialize_and_deserialize_binary_tree.py │ ├── lc_337_house_robber_III │ │ ├── README.md │ │ └── house_robber.py │ ├── lc_404_sum_of_left_leaves │ │ ├── README.md │ │ └── sum_of_left_leaves.py │ ├── lc_437_path_sum_III │ │ ├── README.md │ │ └── path_sum.py │ ├── lc_449_serialize_deserialize_bst │ │ ├── README.md │ │ └── serialize_deserialize_bst.py │ ├── lc_450_delete_bst_node │ │ ├── README.md │ │ └── delete_bst_node.py │ ├── lc_501_find_mode_in_bst │ │ ├── README.md │ │ └── find_mode_in_bst.py │ ├── lc_508_most_frequent_subtree_sum │ │ ├── README.md │ │ └── most_frequent_subtree_sum.py │ ├── lc_513_find_bottom_left_tree_value │ │ ├── README.md │ │ └── find_bottom_left_tree_value.py │ ├── lc_515_find_largest_value_in_each_tree_row │ │ ├── README.md │ │ └── find_largest_value_in_each_tree_row.py │ ├── lc_530_minimum_absolute_diff_in_bst │ │ ├── README.md │ │ └── min_absolute_diff_in_bst.py │ ├── lc_538_convert_bst_to_greater_tree │ │ ├── README.md │ │ └── convert_bst_to_greater_tree.py │ ├── lc_543_diameter_of_a_tree │ │ ├── README.md │ │ └── tree_diameter.py │ ├── lc_563_binary_tree_tilt │ │ ├── README.md │ │ └── binary_tree_tilt.py │ ├── lc_572_subtree_of_another_tree │ │ ├── README.md │ │ └── subtree_of_another_tree.py │ ├── lc_606_construct_string_from_tree │ │ ├── README.md │ │ └── construct_string_from_tree.py │ ├── lc_617_merge_two_binary_trees │ │ ├── README.md │ │ └── merge_two_binary_trees.py │ ├── lc_623_add_one_row_to_tree │ │ ├── README.md │ │ └── add_one_row_to_tree.py │ ├── lc_637_average_of_levels_in_binary_tree │ │ ├── README.md │ │ └── average_of_levels_in_binary_tree.py │ ├── lc_652_find_duplicate_subtrees │ │ ├── README.md │ │ └── find_duplicate_subtrees.py │ ├── lc_653_two_sum_IV │ │ ├── README.md │ │ └── two_sum.py │ ├── lc_654_maximum_binary_tree │ │ ├── README.md │ │ └── maximum_binary_tree.py │ ├── lc_655_print_binary_tree │ │ ├── README.md │ │ └── print_binary_tree.py │ ├── lc_662_maximum_width_of_binary_tree │ │ ├── README.md │ │ └── maximum_width_of_binary_tree.py │ ├── lc_669_trim_a_binary_search_tree │ │ ├── README.md │ │ └── trim_a_binary_search_tree.py │ ├── lc_671_second_minimum_node_in_binary_tree │ │ ├── README.md │ │ └── second_minimum_node_in_binary_tree.py │ ├── lc_687_longest_univalue_path │ │ ├── README.md │ │ └── longest_univalue_path.py │ ├── lc_783_min_distance_between_bst_nodes │ │ ├── README.md │ │ └── min_distance_between_bst_nodes.py │ ├── lc_863_all_nodes_distance_k_binary_tree │ │ ├── README.md │ │ └── all_nodes_distance_k_binary_tree.py │ ├── lc_94_inorder_traversal │ │ ├── README.md │ │ ├── inorder_iterative.py │ │ └── inorder_traversal.py │ ├── lc_95_unique_binary_search_trees_II │ │ ├── README.md │ │ └── unique_binary_search_trees.py │ ├── lc_96_unique_binary_search_trees │ │ ├── README.md │ │ └── unique_binary_search_trees.py │ ├── lc_987_vertical_order_traversal │ │ ├── README.md │ │ └── vertical_order_traversal.py │ ├── lc_988_smallest_string_starting_from_leaf │ │ ├── README.md │ │ └── smallest_string_starting_from_leaf.py │ ├── lc_98_validate_binary_search_tree │ │ ├── README.md │ │ └── validate_binary_search_tree.py │ ├── lc_998_maximum_binary_tree_II │ │ ├── README.md │ │ └── maximum_binary_tree.py │ ├── lc_99_recover_binary_search_trees │ │ ├── README.md │ │ └── recover_binary_search_trees.py │ ├── preorder_inorder_postorder_in_one_traversal │ │ ├── traversals_iterative.py │ │ └── traversals_recursive.py │ ├── root_to_node_path_in_binary_tree │ │ ├── README.md │ │ └── root_to_node.py │ └── top_view_of_binary_tree │ │ ├── README.md │ │ └── top_view.py │ ├── dp │ ├── README.md │ ├── frog_jump │ │ ├── README.md │ │ ├── frog_jump_bottom_up.py │ │ └── frog_jump_top_down.py │ ├── lc_139_word_break_I │ │ └── word_break.py │ ├── lc_152_max_product_subarray │ │ ├── README.md │ │ ├── max_product_brute_force.py │ │ └── max_product_subarray.py │ ├── lc_213_house_robber_2 │ │ ├── README.md │ │ ├── house_robber_bottom_up.py │ │ └── house_robber_top_down.py │ ├── lc_300_longest_increasing_subsequence │ │ ├── README.md │ │ └── longest_increasing_subsequence.py │ ├── lc_472_concatenated_words │ │ ├── README.md │ │ └── concatenated_words.py │ ├── lc_509_fibonacci_number │ │ ├── README.md │ │ ├── fibonacci_bottom_up.py │ │ └── fibonacci_top_down_recursion.py │ ├── lc_70_climbing_stairs │ │ ├── README.md │ │ ├── climbing_stairs_bottom_up.py │ │ └── climbing_stairs_top_down.py │ ├── lc_98_house_robber │ │ ├── README.md │ │ ├── house_robber_bottom_up.py │ │ └── house_robber_top_down_recursion.py │ └── ninja_training │ │ ├── ninja_training_bottom_up.py │ │ └── ninja_training_top_down.py │ ├── graph │ ├── README.md │ ├── bellman_ford_algorithm │ │ ├── README.md │ │ └── bellman_ford_algorithm.py │ ├── detect_cycle_in_directed_graph │ │ ├── detect_cycle_bfs.py │ │ └── detect_cycle_dfs.py │ ├── detect_cycle_in_undirected_graph │ │ ├── detect_cycle_bfs.py │ │ └── detect_cycle_dfs.py │ ├── dijkstras_algorithm │ │ ├── README.md │ │ ├── dijkstras_algorithm_with_min_heap.py │ │ └── dijkstras_algorithm_with_sorted_set.py │ ├── lc_133_clone_graph │ │ ├── README.md │ │ └── clone_graph.py │ ├── lc_200_number_of_islands │ │ ├── README.md │ │ └── number_of_islands_bfs.py │ ├── lc_207_course_schedule_I │ │ ├── README.md │ │ └── course_schedule_I.py │ ├── lc_210_course_schedule_II │ │ ├── README.md │ │ └── course_schedule_II.py │ ├── lc_310_minimum_height_trees │ │ ├── README.md │ │ └── minimum_height_trees.py │ ├── lc_399_evaluate_division │ │ ├── README.md │ │ └── evaluate_division.py │ ├── lc_785_is_graph_bipartite │ │ ├── README.md │ │ ├── bipartite_graph_bfs.py │ │ └── bipartite_graph_dfs.py │ ├── shortest_path_in_weighted_undirected_graph │ │ ├── README.md │ │ ├── shortest_path_1.py │ │ └── shortest_path_2.py │ ├── strongly_connected_components │ │ ├── README.md │ │ └── kosarajus_algorithm.py │ └── topological_sorting │ │ ├── bfs_khans_algorithm.py │ │ └── dfs.py │ ├── hash_tables │ └── lc_676_implement_magic_dictionary │ │ ├── README.md │ │ └── implement_magic_dictionary.py │ ├── heaps │ └── lc_692_top_k_frequent_words │ │ └── README.md │ ├── linkedlist │ ├── README.md │ ├── lc_109_convert_sorted_list_binary_tree │ │ ├── README.md │ │ └── convert_sorted_list_binary_tree.py │ ├── lc_138_copy_list_with_random_pointer │ │ ├── README.md │ │ └── lc_138_copy_list_with_random_pointer.py │ ├── lc_141_linkedlist_cycle │ │ ├── README.md │ │ └── linkedlist_cycle.py │ ├── lc_142_linkedlist_cycle_II │ │ ├── README.md │ │ └── linkedlist_cycle.py │ ├── lc_143_reorder_list │ │ ├── README.md │ │ └── reorder_list.py │ ├── lc_147_insertion_sort │ │ ├── README.md │ │ └── insertion_sort.py │ ├── lc_148_sort_list │ │ ├── README.md │ │ ├── sort_list.py │ │ └── sort_list_2.py │ ├── lc_160_intersection_of_two_linkedlists │ │ ├── README.md │ │ └── intersection_of_two_linkedlists.py │ ├── lc_19_remove_nth_node_from_list │ │ ├── README.md │ │ └── remove_nth_node_from_list.py │ ├── lc_203_remove_linkedlist_elements │ │ ├── README.md │ │ └── remove_linkedlist_elements.py │ ├── lc_206_reverse_linkedlist │ │ ├── README.md │ │ └── reverse_linkedlist.py │ ├── lc_21_merge_two_sorted_lists │ │ ├── README.md │ │ └── merge_two_sorted_lists.py │ ├── lc_234_palindrome_linkedlist │ │ ├── README.md │ │ └── palindrome_linkedlist.py │ ├── lc_237_delete_node_in_linkedlist │ │ ├── README.md │ │ └── delete_node_in_linkedlist.py │ ├── lc_23_merge_k_sorted_lists │ │ ├── README.md │ │ └── merge_k_sorted_lists.py │ ├── lc_24_swap_nodes_in_pairs │ │ ├── README.md │ │ └── swap_nodes_in_pairs.py │ ├── lc_25_reverse_nodes_in_k_groups │ │ ├── README.md │ │ └── reverse_nodes_in_k_groups.py │ ├── lc_2_add_two_numbers │ │ ├── README.md │ │ └── add_two_numbers.py │ ├── lc_328_odd_even_linkedlist │ │ ├── README.md │ │ └── odd_even_linkedlist.py │ ├── lc_445_add_two_numbers_II │ │ ├── README.md │ │ ├── add_two_numbers.py │ │ └── add_two_numbers_II.py │ ├── lc_61_rotate_list │ │ ├── README.md │ │ └── rotate_list.py │ ├── lc_725_split_linkedlist_in_parts │ │ ├── README.md │ │ └── split_linkedlist_in_parts.py │ ├── lc_82_remove_duplicates_from_sorted_list_II │ │ ├── README.md │ │ └── remove_duplicates_from_sorted_list_II.py │ ├── lc_83_remove_duplicates_from_sorted_list │ │ ├── README.md │ │ └── remove_duplicates_from_sorted_list.py │ ├── lc_86_partition_list │ │ ├── README.md │ │ └── partition_list.py │ └── lc_92_reverse_linkedlist_II │ │ ├── README.md │ │ └── reverse_linkedlist_II.py │ ├── recursion │ ├── README.md │ ├── lc_60_permutation_sequence │ │ ├── README.md │ │ └── permutation_sequence.py │ ├── lc_687_longest_univalue_path │ │ ├── README.md │ │ └── longest_univalue_path.py │ ├── lc_698_partition_to_k_equal_sum_subsets │ │ ├── README.md │ │ └── partition_to_k.py │ ├── lc_726_number_of_atoms │ │ ├── README.md │ │ └── number_of_atoms.py │ ├── lc_763_partition_labels │ │ ├── README.md │ │ └── partition_labels.py │ ├── lc_791_custom_sort_string │ │ ├── README.md │ │ └── custom_sort_string.py │ ├── lc_795_number_of_subarrays_with_bounded_maximum │ │ ├── README.md │ │ └── number_of_subarrays.py │ ├── lc_799_champagne_tower │ │ ├── README.md │ │ └── champagne_tower.py │ ├── lc_810_chalkboard_xor_game │ │ ├── README.md │ │ └── chalkboard_xor_game.py │ ├── lc_930_binary_subarrays_with_sum │ │ ├── README.md │ │ └── binary_subarrays_with_sum.py │ ├── lc_975_odd_even_jump │ │ ├── README.md │ │ └── odd_even_jump.py │ └── subset_sum │ │ ├── README.md │ │ └── subset_sum.py │ └── trie │ ├── README.md │ ├── lc_139_word_break_I │ ├── README.md │ └── word_break.py │ ├── lc_208_implement_trie │ ├── README.md │ └── implement_trie.py │ ├── lc_211_design_add_and_search_words_data_structure │ ├── README.md │ └── design_add_and_search_words_data_structure.py │ ├── lc_212_word_search_II │ ├── README.md │ └── word_search_II.py │ ├── lc_336_palindrome_pairs │ ├── README.md │ └── palindrome_pairs.py │ ├── lc_421_max_xor_of_two_numbers_in_array │ ├── README.md │ └── max_xor_of_two_numbers_in_array.py │ ├── lc_648_replace_words │ ├── README.md │ └── replace_words.py │ ├── lc_676_implement_magic_dictionary │ ├── README.md │ └── implement_magic_dictionary.py │ ├── lc_677_map_sum_pairs │ ├── README.md │ └── map_sum_pairs.py │ ├── lc_720_longest_word_in_dictionary │ ├── README.md │ ├── longest_word_in_dictionary.py │ └── longest_word_in_dictionary_2.py │ └── lc_820_short_encoding_of_words │ ├── README.md │ └── short_encoding_of_words.py ├── patterns ├── assets │ ├── all_paths_for_sum_1.png │ ├── all_paths_for_sum_2.png │ ├── bt_level_order_traversal_eg1.png │ ├── bt_level_order_traversal_eg2.png │ ├── bt_reverse_level_order_traversal_eg1.png │ ├── bt_reverse_level_order_traversal_eg2.png │ ├── btree_path_sum_1.png │ ├── btree_path_sum_2.png │ ├── connect_all_level_order_siblings_1.png │ ├── connect_all_level_order_siblings_2.png │ ├── count_paths_sum_1.png │ ├── count_paths_sum_2.png │ ├── find_leaves.png │ ├── happy_number_eg1.png │ ├── happy_number_eg2.png │ ├── level_averages_eg1.png │ ├── level_averages_eg2.png │ ├── level_order_siblings_1.png │ ├── level_order_siblings_2.png │ ├── level_order_successor_1.png │ ├── level_order_successor_2.png │ ├── level_order_successor_3.png │ ├── linkedlist_cycle_start.png │ ├── median_of_stream.png │ ├── merge_intervals.png │ ├── min_depth_of_binary_tree_eg1.png │ ├── min_depth_of_binary_tree_eg2.png │ ├── min_meeting_rooms.png │ ├── path_with_max_sum_1.png │ ├── path_with_max_sum_2.png │ ├── path_with_sequence_1.png │ ├── path_with_sequence_2.png │ ├── reverse_alternating_k-element_sublist.png │ ├── reverse_k_sublist.png │ ├── reverse_linkedlist.png │ ├── reverse_sublist.png │ ├── right_view_of_binary_tree_1.png │ ├── right_view_of_binary_tree_2.png │ ├── rotate_linkedlist_eg1.png │ ├── rotate_linkedlist_eg2.png │ ├── rotation_count_1.png │ ├── rotation_count_2.png │ ├── search_rotated_array_1.png │ ├── search_rotated_array_2.png │ ├── search_rotated_array_with_dups.png │ ├── sum_of_path_numbers_1.png │ ├── sum_of_path_numbers_2.png │ ├── topological_sort_1.png │ ├── topological_sort_2.png │ ├── topological_sort_3.png │ ├── tree_diameter_1.png │ ├── tree_diameter_2.png │ ├── zigzag_traversal_eg1.png │ └── zigzag_traversal_eg2.png └── src │ ├── 10_subsets │ ├── README.md │ ├── balanced_parenthesis │ │ ├── README.md │ │ └── balanced_parenthesis.py │ ├── permutations │ │ ├── README.md │ │ └── permutations.py │ ├── string_permutations_by_changing_case │ │ ├── README.md │ │ └── string_permuations.py │ ├── subsets │ │ ├── README.md │ │ └── subsets.py │ ├── subsets_with_duplicates │ │ ├── README.md │ │ └── subsets_with_duplicates.py │ └── unique_generalized_abbreviation │ │ ├── README.md │ │ └── unique_gen_abbrev.py │ ├── 11_modified_binary_search │ ├── 10_rotation_count │ │ ├── README.md │ │ └── rotation_count.py │ ├── 11_search_in_rotated_array_with_duplicates │ │ ├── README.md │ │ └── search_in_rotated_array.py │ ├── 1_order_agnostic_binary_search │ │ ├── README.md │ │ └── binary_search.py │ ├── 2_ceiling_of_a_number │ │ ├── README.md │ │ └── ceiling_of_number.py │ ├── 2_floor_of_a_number │ │ ├── README.md │ │ └── floor_of_number.py │ ├── 3_next_letter │ │ ├── README.md │ │ └── next_letter.py │ ├── 4_number_range │ │ ├── README.md │ │ └── number_range.py │ ├── 5_search_sorted_infinite_array │ │ ├── README.md │ │ └── search_sorted_infinite_array.py │ ├── 6_minimum_difference_element │ │ ├── README.md │ │ └── minimum_difference_element.py │ ├── 7_bitonic_array_maximum │ │ ├── README.md │ │ └── bitonic_array_maximum.py │ ├── 8_search_bitonic_array │ │ ├── README.md │ │ └── search_bitonic_array.py │ └── 9_search_in_rotated_array │ │ ├── README.md │ │ └── search_in_rotated_array.py │ ├── 12_top_k_elements │ ├── README.md │ ├── connect_ropes │ │ ├── README.md │ │ └── connect_ropes.py │ ├── frequency_sort │ │ ├── README.md │ │ └── frequency_sort.py │ ├── k_closest_numbers │ │ ├── README.md │ │ └── k_closest_numbers.py │ ├── k_closest_point_to_origin │ │ ├── README.md │ │ └── k_closest_point_to_origin.py │ ├── kth_largest_number_in_stream │ │ ├── README.md │ │ └── kth_largest_number_in_stream.py │ ├── kth_smallest_number │ │ ├── README.md │ │ └── kth_smallest_number.py │ ├── top_k_frequent_numbers │ │ ├── README.md │ │ └── top_k_frequent_numbers.py │ └── top_k_numbers │ │ ├── README.md │ │ └── top_k_numbers.py │ ├── 13_k_way_merge │ ├── README.md │ ├── k_pairs_with_largest_sum │ │ ├── README.md │ │ └── k_pairs_with_largest_sum.py │ ├── k_smallest_number_in_m_sorted_list │ │ ├── README.md │ │ └── k_smallest_number.py │ ├── kth_smallest_number_in_sorted_matrix.py │ │ ├── README.md │ │ └── kth_smallest_number_in_sorted_matrix.py │ ├── median_in_sorted_arrays │ │ ├── README.md │ │ └── median_in_sorted_arrays.py │ ├── merge_k_sorted_arrays │ │ ├── README.md │ │ └── merge_k_sorted_arrays.py │ ├── merge_k_sorted_linkedlists │ │ ├── README.md │ │ └── merge_k_sorted_lists.py │ └── smallest_number_range │ │ ├── README.md │ │ └── smallest_number_range.py │ ├── 14_topological_sort │ ├── README.md │ ├── alien_dictionary │ │ ├── README.md │ │ └── alien_dictionary.py │ ├── course_scheduling │ │ ├── README.md │ │ └── course_scheduling.py │ ├── course_scheduling_order │ │ ├── README.md │ │ └── course_scheduling_order.py │ ├── directed_graph_has_cycle │ │ ├── README.md │ │ └── find_cycle.py │ ├── g.py │ ├── task_scheduling │ │ ├── README.md │ │ └── task_scheduling.py │ ├── task_scheduling_order │ │ ├── README.md │ │ └── task_scheduling_order.py │ └── topological_sort │ │ ├── README.md │ │ └── topological_sort.py │ ├── 15_dynamic_programming │ ├── 1_01_knapsack │ │ └── 01_knapsack │ │ │ ├── 01_knapsack_bottom_up_approach.py │ │ │ ├── 01_knapsack_top_down_approach.py │ │ │ └── README.md │ ├── 3_fibonacci_numbers │ │ ├── 1_fibonacci_numbers │ │ │ ├── README.md │ │ │ ├── fibonacci_bottom_up_approach.py │ │ │ └── fibonacci_top_down_approach.py │ │ ├── 2_staircase │ │ │ ├── README.md │ │ │ ├── staircase_bottom_up_approach.py │ │ │ └── staircase_top_down_approach.py │ │ ├── 3_number_factors │ │ │ ├── README.md │ │ │ ├── number_factors_bottom_up_approach.py │ │ │ └── number_factors_top_down_approach.py │ │ ├── 4_minimum_jumps_to_reach_end │ │ │ ├── README.md │ │ │ └── min_jumps_top_down_solution.py │ │ ├── 5_minimum_jumps_with_fee │ │ │ ├── README.md │ │ │ └── min_jumps_with_fee_top_down_solution.py │ │ └── 6_house_theif │ │ │ ├── README.md │ │ │ └── house_theif_top_down_solution.py │ ├── 4_palindromic_sequence │ │ ├── count_of_palindromic_substring │ │ │ ├── README.md │ │ │ └── count_of_ps_top_down_approach.py │ │ ├── longest_palindromic_subsequence │ │ │ ├── README.md │ │ │ └── lps_top_down_approach.py │ │ └── longest_palindromic_substring │ │ │ ├── README.md │ │ │ └── lp_substring_top_down_solution.py │ └── README.md │ ├── 1_sliding_window │ ├── README.md │ ├── average_of_subarrays │ │ ├── README.md │ │ └── averages_of_subarrays.py │ ├── fruits_into_baskets │ │ ├── README.md │ │ └── fruits_into_baskets.py │ ├── longest_sub_array_with_ones_after_replacement │ │ ├── README.md │ │ └── length_of_longest_substring.py │ ├── longest_substr_with_distinct_chars │ │ ├── README.md │ │ └── longest_substr_with_distinct_chars.py │ ├── longest_substr_with_max_k_distinct_chars │ │ ├── README.md │ │ └── longest_subtr.py │ ├── longest_substr_with_same_letters_after_replacement │ │ ├── README.md │ │ └── longest_substr_with_same_letters.py │ ├── maximum_sum_subarray_of_size_K │ │ ├── README.md │ │ └── maximum_sum_subarray_of_size_K.py │ ├── permutation_in_a_string │ │ ├── README.md │ │ └── find_permutation.py │ ├── smallest_subarray_with_greater_sum │ │ ├── README.md │ │ └── smallest_subarray_with_greater_sum.py │ ├── smallest_window_containing_substr │ │ ├── README.md │ │ └── find_substring.py │ ├── string_anagram │ │ ├── README.md │ │ └── string_anagram.py │ ├── subarrays_with_product_less_than_target │ │ ├── README.md │ │ └── find_subarrays.py │ └── words_concatenation │ │ ├── README.MD │ │ └── find_word_concatenation.py │ ├── 2_two_pointers │ ├── README.md │ ├── compare_strings_containing_backspaces │ │ ├── README.md │ │ └── backspace_compare.py │ ├── dutch_national_flag │ │ ├── README.md │ │ └── dutch_flag_sort.py │ ├── minimum_window_sort │ │ ├── README.md │ │ ├── shortest_window_sort.py │ │ └── shortest_window_sort_2.py │ ├── pair_with_target_sum │ │ ├── README.md │ │ └── pair_with_target_sum.py │ ├── quadruple_sum_to_targets.py │ │ ├── README.md │ │ └── search_quadruplets.py │ ├── remove_duplicates │ │ ├── README.md │ │ └── remove_duplicates.py │ ├── remove_keys │ │ ├── README.md │ │ └── remove_keys.py │ ├── square_sorted_array │ │ ├── README.md │ │ └── square_sorted_array.py │ ├── subarrays_with_product_less_than_target │ │ ├── README.md │ │ └── find_subarrays.py │ ├── triplet_sum_close_to_target │ │ ├── README.md │ │ └── triplet_sum_close_to_target.pyt │ ├── triplet_sum_to_zero │ │ ├── README.md │ │ └── triplet_sum_to_zero.py │ └── triplets_with_smaller_sum │ │ ├── README.md │ │ ├── triplets_with_smaller_sum.py │ │ └── triplets_with_smaller_sum_2.py │ ├── 3_fast_and_slow_pointers │ ├── cycle_in_circular_array │ │ ├── README.md │ │ └── cycle_in_circular_array.py │ ├── find_duplicate_number │ │ ├── README.md │ │ └── find_duplicate.py │ ├── happy_number │ │ ├── README.md │ │ └── happy_number.py │ ├── length_of_cycle │ │ ├── README.md │ │ └── length_of_cycle.py │ ├── linkedlist_cycle │ │ ├── README.md │ │ └── find_cycle_length.py │ ├── middle_of_linkedlist │ │ ├── README.md │ │ └── middle_of_linkedlist.py │ ├── palindrome_linkedlist │ │ ├── README.md │ │ └── palindrome_linkedlist.py │ ├── rearrange_linkedlist │ │ ├── README.md │ │ └── reorder_linkedlist.py │ └── start_of_linkedlist_cycle │ │ ├── README.md │ │ └── start_of_linkedlist_cycle.py │ ├── 4_merge_intervals │ ├── 1_merge_intervals │ │ ├── README.md │ │ ├── merge.py │ │ └── merge_2.py │ ├── 2_insert_interval │ │ ├── README.md │ │ └── insert_interval.py │ ├── README.md │ ├── conflicting_appointments │ │ ├── README.md │ │ └── conflicting_appointments.py │ ├── employee_free_time │ │ ├── README.md │ │ └── employee_free_time.py │ ├── find_intervals │ │ ├── README.md │ │ └── find_interval.py │ ├── intervals_intersection │ │ ├── README.md │ │ └── interval_intersection.py │ ├── maximum_cpu_load │ │ ├── README.md │ │ ├── find_max_cpu_load.py │ │ └── find_max_cpu_load_clean.py │ └── minimum_meeting_rooms │ │ ├── README.md │ │ ├── min_meeting_rooms.py │ │ └── min_meeting_rooms_clean.py │ ├── 5_cyclic_sort │ ├── cyclic_sort │ │ ├── README.md │ │ └── cyclic_sort.py │ ├── find_all_duplicate_numbers │ │ ├── README.md │ │ └── find_duplicates.py │ ├── find_all_missing_numbers │ │ ├── README.md │ │ └── find_all_missing_numbers.py │ ├── find_corrupt_pair │ │ ├── README.md │ │ └── find_corrupt_pair.py │ ├── find_duplicate_number │ │ ├── README.md │ │ └── find_duplicate_number.py │ ├── find_first_K_missing_positive_numbers │ │ ├── README.md │ │ └── find_first_k_missing_positive.py │ ├── find_missing_number │ │ ├── README.md │ │ └── find_missing_number.py │ └── find_smallest_missing_positive_number │ │ ├── README.md │ │ └── find_first_smallest_missing_positive.py │ ├── 6_in_place_reversal_of_linkedlist │ ├── README.md │ ├── reverse_alternating_K-element_sub-list │ │ ├── README.md │ │ └── reverse_alternate_k_elements.py │ ├── reverse_every_k_sublist │ │ ├── README.md │ │ ├── reverse_every_k_sublist_iterative.py │ │ └── reverse_every_k_sublist_recursive.py │ ├── reverse_linkedlist │ │ ├── README.md │ │ └── reverse_linkedlist.py │ ├── reverse_sublist │ │ ├── README.md │ │ └── reverse_sublist.py │ └── rotate_linkedlist │ │ ├── README.md │ │ └── rotate_linkedlist.py │ ├── 7_tree_breath_first_search │ ├── README.md │ ├── connect_all_level_order_siblings │ │ ├── README.md │ │ └── connect_level_order_siblings.py │ ├── connect_level_order_siblings │ │ ├── README.md │ │ └── connect_level_order_siblings.py │ ├── largest_value_on_each_level │ │ ├── README.md │ │ └── largest_value_on_each_level.py │ ├── left_view_of_tree │ │ ├── README.md │ │ └── left_view_of_binary_tree.py │ ├── level_averages_in_binary_tree │ │ ├── README.md │ │ └── level_averages_in_binary_tree.py │ ├── level_order_successor │ │ ├── README.md │ │ └── level_order_successor.py │ ├── level_order_traversal │ │ ├── README.md │ │ └── level_order_traversal.py │ ├── max_depth_of_tree │ │ ├── README.md │ │ └── max_depth_of_tree.py │ ├── min_depth_of_binary_tree │ │ ├── README.md │ │ └── find_minimum_depth.py │ ├── reverse_level_order_traversal │ │ ├── README.md │ │ └── reverse_level_order_traversal.py │ ├── right_view_of_binary_tree │ │ ├── README.md │ │ └── right_view_of_binary_tree.py │ └── zigzag_traversal │ │ ├── README.md │ │ └── zigzag_traversal.py │ ├── 8_tree_depth_first_search │ ├── README.md │ ├── all_paths_for_a_sum │ │ ├── README.md │ │ └── find_paths.py │ ├── btree_path_sum │ │ ├── README.md │ │ └── btree_path_sum.py │ ├── count_paths_for_sum │ │ ├── README.md │ │ └── count_paths_for_sum.py │ ├── path_with_given_sequence │ │ ├── README.md │ │ └── path_with_given_sequence.py │ ├── path_with_maximum_sum │ │ ├── README.md │ │ └── path_with_max_sum.py │ ├── root_to_leaf_paths │ │ ├── README.md │ │ └── root_to_leaf_paths.py │ ├── sum_of_path_numbers │ │ ├── README.md │ │ └── sum_of_path_numbers.py │ └── tree_diameter │ │ ├── README.md │ │ └── tree_diameter.py │ └── 9_two_heaps │ ├── 1_median_of_number_stream │ ├── README.md │ └── median_of_number_stream.py │ ├── 2_sliding_window_median │ ├── README.md │ └── sliding_window_median.py │ ├── 3_maximize_capital │ ├── README.md │ └── maximize_capital.py │ └── 4_next_interval │ ├── README.md │ └── next_interval.py └── recursion_crash_course ├── README.md └── src ├── 1_recursion_with_strings ├── 1_reverse_string.py └── 2_palindrome.py ├── 2_recursion_with_numbers ├── 1_decimal_to_binary.py └── 2_sum_of_natural_numbers.py └── 3_divide_and_conquer ├── 1_fibonacci.py ├── 2_binary_search.py ├── 3_merge_sort.py ├── 3_merge_sort_2.py ├── 4_reverse_linkedlist.py ├── 5_merge_two_sorted_list.py ├── 6_insert_into_binary_search_tree.py ├── 7_get_leaf_nodes.py └── 8_depth_first_search.py /.gitignore: -------------------------------------------------------------------------------- 1 | /__pycache__ -------------------------------------------------------------------------------- /EPI_prep/assets/add_two_linkedlist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/assets/add_two_linkedlist.png -------------------------------------------------------------------------------- /EPI_prep/assets/after_cyclic_shift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/assets/after_cyclic_shift.png -------------------------------------------------------------------------------- /EPI_prep/assets/before_cyclic_shift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/assets/before_cyclic_shift.png -------------------------------------------------------------------------------- /EPI_prep/assets/bst.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/assets/bst.png -------------------------------------------------------------------------------- /EPI_prep/assets/bst_min_height.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/assets/bst_min_height.png -------------------------------------------------------------------------------- /EPI_prep/assets/doubly_linkedlist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/assets/doubly_linkedlist.png -------------------------------------------------------------------------------- /EPI_prep/assets/even_odd_merge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/assets/even_odd_merge.png -------------------------------------------------------------------------------- /EPI_prep/assets/graph_undirected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/assets/graph_undirected.png -------------------------------------------------------------------------------- /EPI_prep/assets/graph_with_weights.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/assets/graph_with_weights.png -------------------------------------------------------------------------------- /EPI_prep/assets/graphs_dag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/assets/graphs_dag.png -------------------------------------------------------------------------------- /EPI_prep/assets/inc_dec_array.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/assets/inc_dec_array.png -------------------------------------------------------------------------------- /EPI_prep/assets/list_pivoting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/assets/list_pivoting.png -------------------------------------------------------------------------------- /EPI_prep/assets/max_heap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/assets/max_heap.png -------------------------------------------------------------------------------- /EPI_prep/assets/max_heap_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/assets/max_heap_delete.png -------------------------------------------------------------------------------- /EPI_prep/assets/merge_two_lists.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/assets/merge_two_lists.png -------------------------------------------------------------------------------- /EPI_prep/assets/overlapping_lists.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/assets/overlapping_lists.png -------------------------------------------------------------------------------- /EPI_prep/assets/overlapping_lists_with_cycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/assets/overlapping_lists_with_cycle.png -------------------------------------------------------------------------------- /EPI_prep/assets/remove_dups_from_sorted_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/assets/remove_dups_from_sorted_list.png -------------------------------------------------------------------------------- /EPI_prep/assets/right_sibling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/assets/right_sibling.png -------------------------------------------------------------------------------- /EPI_prep/assets/singly_linkedlist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/assets/singly_linkedlist.png -------------------------------------------------------------------------------- /EPI_prep/assets/symmetric_binary_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/assets/symmetric_binary_tree.png -------------------------------------------------------------------------------- /EPI_prep/src/binary_search_trees/0_search_bst/README.md: -------------------------------------------------------------------------------- 1 | # Search Binary Search Tree 2 | 3 | Write a function to check if a given value exists in a BST 4 | 5 | ![Binary Search Tree](../../../assets/bst.png) 6 | -------------------------------------------------------------------------------- /EPI_prep/src/binary_search_trees/10_range_look_up_problem/README.md: -------------------------------------------------------------------------------- 1 | # The Range Lookup Problem 2 | 3 |
4 | 5 | Write a program that takes as input a BST and an interval and returns the BST keys that lie in the interval 6 | 7 |
8 | 9 | - Hint: How many edges are traversed when the successor function is repeatedly called m times? 10 | 11 |
12 | 13 | ### Examples 14 | In Figure below 15 | - if the interval is [2, 5], you should return [2, 3, 5] 16 | - if the interval is [16, 31], you should return [17, 19, 23, 29, 31] 17 | - if the interval is [31, 53], you should return [31, 37, 41, 43, 47, 53] 18 | 19 | ![Binary Search Tree](../../../assets/bst.png) 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /EPI_prep/src/binary_search_trees/1_check_if_bst_satisfies_bst_property/README.md: -------------------------------------------------------------------------------- 1 | # Test If A Binary Search Tree Satisfies the BST Property 2 | 3 | Write a Program that takes as input a binary tree and checks if the tree satisfies the BST property. 4 | 5 | * Hint: ls it correct to check for each node that its key is greater than or equal to the key at its left child and less than or equal to the key at its right child? 6 | 7 | 8 | ![Binary Search Tree](../../../assets/bst.png) -------------------------------------------------------------------------------- /EPI_prep/src/binary_search_trees/2_find_first_key_greater_than_a_value_in_bst/README.md: -------------------------------------------------------------------------------- 1 | # Find the First Key Greater Than A Given Value In A BST 2 | 3 |
4 | 5 | Write a program that takes as input a BST and a value, and retums the first key that would appear in an inorder traversal which is greater than the input value. 6 | For example, when applied to the BST in the Figure below, you should return 29 for input 23. 7 | 8 | ### Example 1 9 | Input: tree, 23 10 | Output: 29 11 | 12 |
13 | 14 | ### Example 2 15 | Input: tree, 2 16 | Output: 3 17 | 18 |
19 | 20 | ### Example 3 21 | Input: tree, 53 22 | Output: None 23 | 24 | ![Binary Search Tree](../../../assets/bst.png) -------------------------------------------------------------------------------- /EPI_prep/src/binary_search_trees/3_k_largest_in_bst/README.md: -------------------------------------------------------------------------------- 1 | # Find The K Largest Elements In A BST 2 | 3 |
4 | 5 | Write a program that takes as input a BST and an integer k, and retums the k largest elements in the BST in decreasing order. 6 | 7 | ### Example 1 8 | Input: tree, k = 3 9 | Output: [53, 47, 43] 10 | 11 |
12 | 13 | ### Example 2 14 | Input: tree, k = 2 15 | Output: [53, 47] 16 | 17 |
18 | 19 | ![Binary Search Tree](../../../assets/bst.png) -------------------------------------------------------------------------------- /EPI_prep/src/binary_search_trees/4_lca_in_a_bst/README.md: -------------------------------------------------------------------------------- 1 | # Compute The LCA In A BST 2 | 3 |
4 | 5 | Write a program that takes as input a BST and an integer k, and retums the k largest elements in the BST in decreasing order. 6 | 7 | ### Example 1 8 | Input: tree, k = 3 9 | Output: [53, 47, 43] 10 | 11 |
12 | 13 | ### Example 2 14 | Input: tree, k = 2 15 | Output: [53, 47] 16 | 17 |
18 | 19 | ![Binary Search Tree](../../../assets/bst.png) -------------------------------------------------------------------------------- /EPI_prep/src/binary_search_trees/5.1_reconstruct_bst_from_post_order_traversal_data/README.md: -------------------------------------------------------------------------------- 1 | # Reconstruct A BST From Postorder Traversal Data 2 | 3 |
4 | 5 | Write a program to reconstruct the BST from a post order sequence 6 | -------------------------------------------------------------------------------- /EPI_prep/src/binary_search_trees/5_reconstruct_bst_from_preorder_traversal_data/README.md: -------------------------------------------------------------------------------- 1 | # Reconstruct A BST From Preorder Traversal Data 2 | 3 |
4 | 5 | Write a program to reconstruct the BST from a preorder sequence 6 | -------------------------------------------------------------------------------- /EPI_prep/src/binary_search_trees/6_closest_entries_in_3_sorted_arrays/README.md: -------------------------------------------------------------------------------- 1 | # Find The Closest Entries In Three Sorted Arrays 2 | 3 |
4 | 5 | Design an algorithm that takes three sorted arrays and returns one entry from each such that the minimum interval containing these three entries is as small as possible. 6 | 7 | 8 | 9 | ### Example 1 10 | Input: [[5,10,15], [3,6,9,12,15],[8,16,24]] 11 | Output: [15,15,16] 12 | Explanation: since this array [15, 15, 16] has the minimum interval 13 | -------------------------------------------------------------------------------- /EPI_prep/src/binary_search_trees/7_enumerate_numbers_of_the_form_a+b_sqrt2/README.md: -------------------------------------------------------------------------------- 1 | # Enumerate Numbers Of The Form a + b sqrt(2) 2 | 3 |
4 | Design an algorithm for efficiently computing the k smallest numbers of the form a + b sqrt(2) for nonnegative integers a and b. 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /EPI_prep/src/binary_search_trees/8_build_minimum_height_bst/README.md: -------------------------------------------------------------------------------- 1 | # Build A Minimum Height BST From A Sorted Array 2 | 3 |
4 | Given a sorted array, the number of BSTs that can be built on the entries in the array grows enormously with its size. 5 | Some of these trees are skewed, and are closer to lists; others are more balanced. 6 | How would you build a BST of minimum possible height from a sorted array? 7 | 8 |
9 | 10 | - Hint; Which element should be the root? 11 | 12 | 13 | ![Multiple BSTs From the Same Array](../../../assets/bst_min_height.png) 14 | 15 | 16 |
17 | From the figure above, given a sorted array [1,2,3], the tree with the minimum height is the third tree 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /EPI_prep/src/binary_trees/10_compute_sucessor/README.md: -------------------------------------------------------------------------------- 1 | # Compute Succesor 2 | 3 | * Design an algorithm that computes the successor of a node in a binary tree. Assume that each node stores its parent. -------------------------------------------------------------------------------- /EPI_prep/src/binary_trees/11.1_preorder_traversal_in_constant_space/README.md: -------------------------------------------------------------------------------- 1 | # Implement An Preorder Traversal With O(1) Space 2 | 3 | * Write a nonrecursive program for computing the preorder traversal sequence for a binary tree. Assume nodes have parent fields. -------------------------------------------------------------------------------- /EPI_prep/src/binary_trees/11.2_postorder_traversal_in_constant_space/README.md: -------------------------------------------------------------------------------- 1 | # Implement An Postorder Traversal With O(1) Space 2 | 3 | * Write a nonrecursive program for computing the postorder traversal sequence for a binary tree. Assume nodes have parent fields. -------------------------------------------------------------------------------- /EPI_prep/src/binary_trees/11_inorder_traversal_in_constant_space/README.md: -------------------------------------------------------------------------------- 1 | # Implement An Inorder Traversal With O(1) Space 2 | 3 | * Write a nonrecursive program for computing the inorder traversal sequence for a binary tree. Assume nodes have parent fields. -------------------------------------------------------------------------------- /EPI_prep/src/binary_trees/12_reconstruct_binary_tree_from_preorder_inorder_traversal/README.md: -------------------------------------------------------------------------------- 1 | # Reconstruct A Binary Tree From Traversal Data 2 | 3 | * Given an inorder traversal sequence and a preorder traversal sequence of a binary tree 4 | write a program to reconstruct the tree. Assume each node has a unique key. -------------------------------------------------------------------------------- /EPI_prep/src/binary_trees/13_reconstruct_bt_from_preorder_traversal/README.md: -------------------------------------------------------------------------------- 1 | # Reconstruct A Binary Tree From A Preorder Traversal With Markers 2 | 3 | * Design an algorithm for reconstructing a binary tree from a preorder traversal visit sequence that uses null to mark empty children. -------------------------------------------------------------------------------- /EPI_prep/src/binary_trees/14_form_a_linkedlist_from_leaves_of_bt/README.md: -------------------------------------------------------------------------------- 1 | # Form A Linkedlist From The Leaves Of A Binary Tree 2 | 3 | * Given a binary tree, compute a linked list from the leaves of the binary tree. The leaves should appear in left-to-right order -------------------------------------------------------------------------------- /EPI_prep/src/binary_trees/15_compute_exterior_of_binary_tree/README.md: -------------------------------------------------------------------------------- 1 | # Compute The Exterior Of A Binary Tree 2 | 3 | * Write a program that computes the exterior of a binary tree. 4 | -------------------------------------------------------------------------------- /EPI_prep/src/binary_trees/16_compute_right_sibling_tree/README.md: -------------------------------------------------------------------------------- 1 | # Compute The Right Sibling Tree 2 | 3 | * Write a program that takes a perfect binary tree, and sets each node's level-next field to the node on its right, if one exists. 4 | 5 | * Note - A perfect binary tree is a full binary tree in which all leaves are at the same depth, and in which every parent has two children. 6 | 7 | ![Right Sibling Tree Image](../../../assets/right_sibling.png) 8 | -------------------------------------------------------------------------------- /EPI_prep/src/binary_trees/1_is_binary_tree_height_balanced/README.md: -------------------------------------------------------------------------------- 1 | # Is Binary Tree Height Balanced 2 | 3 | * Write a program that takes as input the root of a binary tree and checks whether the tree is height- balanced. 4 | 5 | A binary tree is said to be height-balanced if for each node in the tree, 6 | the difference in the height of its left and right subtrees is at most one. 7 | A perfect binary tree is height-balanced, as is a complete binary tree. 8 | A height-balanced binary tree does not have to be perfect or complete. 9 | -------------------------------------------------------------------------------- /EPI_prep/src/binary_trees/2_is_binary_tree_symmetric/README.md: -------------------------------------------------------------------------------- 1 | # Test If A Binary Tree Is Symmetric 2 | 3 | Write a program that checks whether a binary tree is symmetric. 4 | 5 | ![Alt text](./../../../assets/symmetric_binary_tree.png) -------------------------------------------------------------------------------- /EPI_prep/src/binary_trees/3_lca/README.md: -------------------------------------------------------------------------------- 1 | ## Design an algorithm for computing the LCA of two nodes in a binary tree in which nodes do not have a parent field. -------------------------------------------------------------------------------- /EPI_prep/src/binary_trees/4_lca_with_parent_pointers/README.md: -------------------------------------------------------------------------------- 1 | ## COMPUTE THE LCA WHEN NODES HAVE PARENT POINTERS 2 | 3 | * Given two nodes in a binary tree, design an algorithm that computes their LCA. Assume that each node has a parent pointer. -------------------------------------------------------------------------------- /EPI_prep/src/binary_trees/5_sum_root_to_leaf/README.md: -------------------------------------------------------------------------------- 1 | ## Sum Root to Leaf Paths 2 | 3 | * Design an algorithm to compute the sum of the binary numbers represented by the root-to-leaf paths. -------------------------------------------------------------------------------- /EPI_prep/src/binary_trees/6.1_root_to_leaf_sum_all_paths/README.md: -------------------------------------------------------------------------------- 1 | ## Find All Root to Leaf Paths With Specified Sum 2 | 3 | * Write a program which takes the same inputs as in Problem 6 and returns all the paths to leaves whose weighte quals 4 | the specified sum -------------------------------------------------------------------------------- /EPI_prep/src/binary_trees/6_root_leaf_path_with_specified_sum/README.md: -------------------------------------------------------------------------------- 1 | ## Find Root to Leaf Path With Specified Sum 2 | 3 | * Write a program which takes as input an integer and a binary tree with integer node weights, 4 | and checks if there exists a leaf whose path weight equals the given integer. -------------------------------------------------------------------------------- /EPI_prep/src/binary_trees/7_inorder_traversal_without_recursion/README.md: -------------------------------------------------------------------------------- 1 | ## Implement an inorder traversal without recursion 2 | 3 | * Write a program which takes as input a binary tree and performs an inorder traversal of the tree. 4 | Do not use recursion. Nodes do not contain parent references. -------------------------------------------------------------------------------- /EPI_prep/src/binary_trees/8_preorder_traversal_without_recursion/README.md: -------------------------------------------------------------------------------- 1 | ## Implement an Preorder traversal without recursion 2 | 3 | * Write a program which takes as input a binary tree and performs an preorder traversal of the tree. 4 | Do not use recursion. Nodes do not contain parent references. -------------------------------------------------------------------------------- /EPI_prep/src/binary_trees/9.1_kth_node_in_inorder_traversal/README.md: -------------------------------------------------------------------------------- 1 | ## Compute the Kth node in an Inorder Traversal 2 | 3 | * Write a program that efficiently computes the kth node appearing in an inorder traversal. 4 | Assume that each node stores the number of nodes in the subtree rooted at that node. -------------------------------------------------------------------------------- /EPI_prep/src/binary_trees/9_kth_node_in_inorder_traversal/README.md: -------------------------------------------------------------------------------- 1 | ## Compute the Kth node in an Inorder Traversal 2 | 3 | * Write a program that efficiently computes the kth node appearing in an inorder traversal. 4 | Assume that each node stores the number of nodes in the subtree rooted at that node. -------------------------------------------------------------------------------- /EPI_prep/src/graphs/1_search_maze/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/EPI_prep/src/graphs/1_search_maze/README.md -------------------------------------------------------------------------------- /EPI_prep/src/heaps/1_merge_sorted_arrays/README.md: -------------------------------------------------------------------------------- 1 | # Merge Sorted Arrays 2 | 3 | 4 | Write a program that takes as input a set of sorted sequences and computes the union of these sequences as a sorted sequence. 5 | 6 |
7 | 8 | - Hint: Which part of each sequence is significant as the algorithm executes? 9 | 10 |
11 | 12 | ### Example 1 13 | - input: [[3,5,7], [0,5], [0,6,28]] 14 | - output: [0, 0, 3, 5, 5, 6, 7, 28] 15 | 16 | -------------------------------------------------------------------------------- /EPI_prep/src/heaps/2_sort_increasing_decreasing_array/README.md: -------------------------------------------------------------------------------- 1 | # Sort An Increasing Decreasing Array 2 | 3 | 4 | Design an efficient algorithm for sorting a k-increasing-decreasing array. 5 | 6 |
7 | 8 | - An array is said to be k-increasing-decreasing if elements repeatedly increase up to a certain index after which they decrease, 9 | then again increase, a total of k times. This is illustrated in Figure below 10 | 11 |
12 | 13 | ![Increasing Decreasing Array](../../../assets/inc_dec_array.png) 14 | 15 |
16 |
17 | 18 | ### Example 1 19 | - input: [57, 131, 493, 221, 294, 339, 418, 452, 190, 442] 20 | - output: [0, 0, 3, 5, 5, 6, 7, 28] 21 | 22 | -------------------------------------------------------------------------------- /EPI_prep/src/heaps/3_sort_almost_sorted_array/README.md: -------------------------------------------------------------------------------- 1 | # Sort An Almost Sorted Array 2 | 3 | Write a Program which takes as input a very long sequence of numbers and prints the numbers in sorted order. Each number is at most k away from its correctly sorted position. 4 | (Such an array is sometimes referred to as being k-sorted.) For example,no number in the sequence(3, -1,2,6,4,5,8] is more than 2 away from its final sorted position. 5 | 6 |
7 | 8 | - How many numbers must you read after reading the ith number to be sure you can place it in the correct location? 9 | 10 |
11 | 12 |
13 | 14 | ### Example 1 15 | - input: [3,-1,2,6,4,5,8], k = 2 16 | - output: [-1, 2, 3, 4, 5, 6, 8] 17 | 18 | ### Example 2 19 | - input: [-4, 0, 1, -3,], k = 3 20 | - output: [-4, -3, 0, 1] 21 | 22 | -------------------------------------------------------------------------------- /EPI_prep/src/heaps/5_compute_median_from_a_stream/README.md: -------------------------------------------------------------------------------- 1 | # Compute Median From A Stream 2 | 3 | You want to compute the running median of a sequence of numbers. The sequence is presented to you in a streaming fashion-you 4 | cannot back up to read an earlier value, and you need to output the median after reading in each new element. 5 | For example, if the input is 1,0,3,5,2,0,1 the output is 1, 0.5, 1, 2, 2, 1.5, 1 6 | 7 |
8 | 9 | Design an algorithm for computing the running median of a sequence. 10 | 11 |
12 | 13 | ### Example 1 14 | - input: [1,0,3,5,2,0,1] 15 | - output: [1,0.5,1,2,2,1.5,1] 16 | 17 | 18 | ### Example 2 19 | - input: [11,10,31,52,2,7,1] 20 | - output: [11, 10.5, 11, 21.0, 11, 10.5, 10] -------------------------------------------------------------------------------- /EPI_prep/src/heaps/6_k_largest_elements_in_a_heap/README.md: -------------------------------------------------------------------------------- 1 | # Compute Median From A Stream 2 | 3 | Given a max-heap, represented as an array A, design an algorithm that computes the k largest elements stored in the max-heap. 4 | You cannot modify the heap. 5 | 6 |
7 | 8 |
9 | 10 | ### Example 1 11 | - input: [561,314,401,28,156,359,271,11,3] 12 | - output: [561,401, 359, 314] 13 | 14 | 15 |
16 | 17 |
18 | 19 | ![Max Heap](../../../assets/max_heap.png) -------------------------------------------------------------------------------- /EPI_prep/src/linkedlist/1.1_merge_two_sorted_doubly_linkedlist/README.md: -------------------------------------------------------------------------------- 1 | # Merge Two Sorted Doubly Linked Lists 2 | 3 | Consider two doubly linked lists in which each node holds a number. Assume the lists are sorted, i.e., numbers in the lists appear in ascending order within each list. 4 | The *merge* of the two lists is a list consisting of the nodes of the two lists in which numbers appear in ascending order. 5 | 6 | 7 | Write a program that takes two lists, assumed to be sorted, and returns their merge. The only field your program can change in a node is its next field. 8 | 9 | -------------------------------------------------------------------------------- /EPI_prep/src/linkedlist/10_even_odd_merge/README.md: -------------------------------------------------------------------------------- 1 | # Implement Even Odd Merge 2 | 3 | Write a program that computes the even-odd merge. 4 | See example below: 5 |

6 | 7 | 8 | ![Linkedlist Before Cyclic SHift](../../../assets/even_odd_merge.png) 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /EPI_prep/src/linkedlist/11_palindromic_linkedlist/README.md: -------------------------------------------------------------------------------- 1 | # Implement Even Odd Merge 2 | 3 | Write a program that tests whether a singly linked list is palindromic. 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /EPI_prep/src/linkedlist/12_implement_list_pivoting/README.md: -------------------------------------------------------------------------------- 1 | # Implement List Pivoting 2 | 3 | Implement a function which takes as input a singly linked list and an integer k and performs a pivot of the list with respect to k. The relative ordering of nodes that appear before k, and after k, must remain unchanged; the same must hold for nodes holding keys equal to k. 4 | 5 |

6 | 7 | ![List Pivoting](../../../assets/list_pivoting.png) 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /EPI_prep/src/linkedlist/13_add_two_linkedlists/README.md: -------------------------------------------------------------------------------- 1 | # Add Two LinkedLists 2 | 3 | 4 | Write a program which takes two singly linked lists of digits, and returns the list corresponding to the sum of the integers they represent. The least significant digit comes first. 5 | 6 |

7 | 8 | ![Add Two LinkedLists](../../../assets/add_two_linkedlist.png) 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /EPI_prep/src/linkedlist/1_merge_two_sorted_lists/README.md: -------------------------------------------------------------------------------- 1 | # Merge Two Sorted Lists 2 | 3 | Consider two singly linked lists in which each node holds a number. Assume the lists are sorted, i.e., numbers in the lists appear in ascending order within each list. 4 | The *merge* of the two lists is a list consisting of the nodes of the two lists in which numbers appear in ascending order. Merge is illustrated in Figure below. 5 | 6 | 7 | Write a program that takes two lists, assumed to be sorted, and returns their merge. The only field your program can change in a node is its next field. 8 | 9 | - *Hint*: Two sorted arrays can be merged using two indices. For lists, take care when one iterator reaches the end. 10 | 11 |

12 | ![Merge Two Sorted Lists](../../../assets/merge_two_lists.png) 13 | 14 | -------------------------------------------------------------------------------- /EPI_prep/src/linkedlist/2.1_reverse_singly_linkedlist/README.md: -------------------------------------------------------------------------------- 1 | # Reverse A Singly LinkedList 2 | 3 | Write a program which takes a singly linked list L and reverses it 4 | 5 | 6 |

7 | 8 | ### Example 1 9 | - input: [2, 3, 5, 7, 11] 10 | - output = [11, 7, 5, 3, 2] 11 | 12 | -------------------------------------------------------------------------------- /EPI_prep/src/linkedlist/2_reverse_a_single_sublist/README.md: -------------------------------------------------------------------------------- 1 | # Reverse A Sublist 2 | 3 | Write a program which takes a singly linked list L and two integers s and f as arguments, and reverses the order of the nodes from the sth node to fth node, inclusive. 4 | The numbering begins at 1., i.e., the head node is the first node. Do not allocate additional nodes. 5 | 6 | Write a program that takes two lists, assumed to be sorted, and returns their merge. The only field your program can change in a node is its next field. 7 | 8 | 9 |

10 | 11 | ### Example 1 12 | - input: [2, 3, 5, 7, 11], s = 2, f = 4 13 | - output = [2, 7, 5, 3, 11] 14 | 15 | -------------------------------------------------------------------------------- /EPI_prep/src/linkedlist/3_test_for_cyclicity/README.md: -------------------------------------------------------------------------------- 1 | # Test For Cyclicity 2 | 3 | 4 | Write a program that takes the head of a singly linked list and retums null if there does not exist a cycle, and the node at the start of the cycle, if a cycle is present. 5 | (You do not know the length of the list in advance.) 6 | 7 | - *Hint*: Consider using two iterators, one fast and one slow. 8 | 9 | 10 |

11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /EPI_prep/src/linkedlist/4_test_for_overlapping_lists/README.md: -------------------------------------------------------------------------------- 1 | # Test For Overlapping List - Lists Are Cycle Free 2 | 3 | Given two singly linked lists there may be list nodes that are common to both. (This may not be a bug-it may be desirable from the perspective of reducing memory footprint, as in the flyweight pattern, or maintaining a canonical form). 4 | For example, the lists in Figure below overlap at Node I. 5 | 6 | - Write a Program that takes two cycle-free singly linked lists, and determines if there exists a node that is common to both lists. 7 | 8 | 9 |

10 | 11 | ![Overlapping Singly LinkedLists](../../../assets/overlapping_lists.png) 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /EPI_prep/src/linkedlist/6_delete_node_from_singly_linkedlist/README.md: -------------------------------------------------------------------------------- 1 | # Delete Node From Singly LinkedList 2 | 3 | Write a program which deletes a node in a singly linked list. The input node is guaranteed not to be the tail node. 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /EPI_prep/src/linkedlist/7_remove_kth_last_element_from_list/README.md: -------------------------------------------------------------------------------- 1 | # Remove Kth Last Element From List 2 | 3 | Given a singly linked list and an integer k, write a program to remove the kth last element from the list. 4 | Your algorithm cannot use more than a few words of storage, regardless of the length of the list. 5 | In particular, you cannot assume that it is possible to record the length of the list. 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /EPI_prep/src/linkedlist/8_remove_duplicates_from_sorted_list/README.md: -------------------------------------------------------------------------------- 1 | # Remove Duplicates From Sorted Lists 2 | 3 | Write a program that takes as input a singly linked list of integers in sorted order, and removes duplicates from it. The list should be sorted. 4 | See example below: 5 | 6 | ![Remove Duplicates From Sorted Lists](../../../assets/remove_dups_from_sorted_list.png) 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /EPI_prep/src/linkedlist/9_cyclic_right_shift_of_singly_linkedlist/README.md: -------------------------------------------------------------------------------- 1 | # Implement Cyclic Right Shift For Singly LinkedList 2 | 3 | Write a program that takes as input a singly linked list and a nonnegative integer k, and retums the list cyclically shifted to the right by k. 4 | See example below after shifting linkedlist 3 times (k=3): 5 |

6 | 7 | ## Before Cyclic Shift 8 |
9 | 10 | ![Linkedlist Before Cyclic SHift](../../../assets/before_cyclic_shift.png) 11 |

12 | 13 | ## After Cyclic Shift 14 |
15 | 16 | ![Linkedlist After Cyclic SHift](../../../assets/after_cyclic_shift.png) 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /EPI_prep/src/recursion/0_greatest_common_divisor/gcd.py: -------------------------------------------------------------------------------- 1 | def gcd(x, y): 2 | return x if y == 0 else gcd(y, x % y) 3 | 4 | print(gcd(156, 36)) # 12 5 | print(gcd(64, 36)) #4 -------------------------------------------------------------------------------- /EPI_prep/src/recursion/1_towers_of_hanoi/towers_of_hanoi.py: -------------------------------------------------------------------------------- 1 | # Time O(2^N) 2 | # Space O(N) 3 | # where N is the number of rings 4 | 5 | NUM_PEGS = 3 6 | def compute_towers_of_hanoi(num_of_rings): 7 | def compute_towers(num_of_rings, from_peg, to_peg, use_peg): 8 | if num_of_rings > 0: 9 | compute_towers(num_of_rings - 1, from_peg, use_peg, to_peg) 10 | pegs[to_peg].append(pegs[from_peg].pop()) 11 | result.append([from_peg, to_peg]) 12 | 13 | compute_towers(num_of_rings - 1, use_peg, to_peg, from_peg) 14 | 15 | result = [] 16 | pegs = [list(reversed(range(1, num_of_rings + 1)))] + [[] for _ in range(1, NUM_PEGS)] 17 | 18 | compute_towers(num_of_rings, 0, 1, 2) 19 | 20 | return result 21 | 22 | print(compute_towers_of_hanoi(3)) 23 | 24 | -------------------------------------------------------------------------------- /EPI_prep/src/recursion/5_subset_of_size_k/README.md: -------------------------------------------------------------------------------- 1 | ### Subsets of size K 2 | 3 | Write a program which computes all size k subsets of {1,,2,...n}, 4 | where k and n are Program inputs. 5 | 6 | #### Example 7 | * For example, if k = 2 and n = 5, then the result is the following: 8 | * [[1, 2], [1,3], [1,4], [1,5], [2,3], [2,4], [2,5], [3,4], [3,5], [4,5]] -------------------------------------------------------------------------------- /EPI_prep/src/recursion/5_subset_of_size_k/combinations.py: -------------------------------------------------------------------------------- 1 | def combinations(n, k): 2 | def directed_combinations(offset, partial_combination): 3 | if len(partial_combination) == k: 4 | result.append(partial_combination) 5 | return 6 | 7 | num_remaining = k - len(partial_combination) 8 | i = offset 9 | 10 | while i <= n and num_remaining <= n - i + 1: 11 | directed_combinations(i+1, partial_combination + [i]) 12 | i += 1 13 | 14 | result = [] 15 | directed_combinations(1, []) 16 | return result 17 | 18 | 19 | print(combinations(4, 2)) 20 | 21 | -------------------------------------------------------------------------------- /EPI_prep/src/recursion/6_generate_balanced_parentheses/README.md: -------------------------------------------------------------------------------- 1 | ### Generate Balanced Parentheses 2 | 3 | Write a program that takes as input a number and retums all the strings with that number of matched pairs of parens. 4 | 5 | #### Example 1: 6 | * Give n = 1 7 | * Return [((0)), (00), (0)0,0(0),000}] 8 | 9 | 10 | #### Example 2: 11 | * Give n = 2 12 | * Return [((0)), (00), (0)0,0(0),000}] 13 | 14 | #### Example 3: 15 | * Give n = 3 16 | * Return [((0)), (00), (0)0,0(0),000}] -------------------------------------------------------------------------------- /algorithms/assets/kruskals_sorted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/algorithms/assets/kruskals_sorted.png -------------------------------------------------------------------------------- /algorithms/src/graph_algorithms/bfs/README.md: -------------------------------------------------------------------------------- 1 | https://www.programiz.com/dsa/graph-bfs -------------------------------------------------------------------------------- /algorithms/src/graph_algorithms/bfs/breath_first_search.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | def bfs(graph, vertex): 4 | if vertex: 5 | result, visited = [], set(vertex) 6 | queue = deque([vertex]) 7 | 8 | while queue: 9 | curr_node = queue.popleft() 10 | result.append(curr_node) 11 | 12 | for node in graph[curr_node]: 13 | if node not in visited: 14 | queue.append(node) 15 | visited.add(node) 16 | 17 | return result 18 | 19 | graph = { 20 | "a": ["b", "c"], 21 | "b": ["a", "d", "e"], 22 | "c": ["a", "e"], 23 | "d": ["b", "e", "f"], 24 | "e": ["d", "f"], 25 | "f": ["d", "e"], 26 | } 27 | 28 | print(bfs(graph, "a")) -------------------------------------------------------------------------------- /algorithms/src/graph_algorithms/dfs/README.md: -------------------------------------------------------------------------------- 1 | https://www.programiz.com/dsa/graph-dfs -------------------------------------------------------------------------------- /algorithms/src/graph_algorithms/dfs/depth_first_search.py: -------------------------------------------------------------------------------- 1 | 2 | def dfs(graph, vertex): 3 | if vertex: 4 | result, visited, stack = [], set(vertex), [vertex] 5 | 6 | while stack: 7 | curr_node = stack.pop() 8 | result.append(curr_node) 9 | 10 | for node in graph[curr_node]: 11 | if node not in visited: 12 | stack.append(node) 13 | visited.add(node) 14 | 15 | return result 16 | 17 | graph = { 18 | "a": ["b", "c"], 19 | "b": ["a", "d", "e"], 20 | "c": ["a", "e"], 21 | "d": ["b", "e", "f"], 22 | "e": ["d", "f"], 23 | "f": ["d", "e"], 24 | } 25 | 26 | print(dfs(graph, "a")) -------------------------------------------------------------------------------- /algorithms/src/graph_algorithms/floyd_warshall_algorithm/floyd_warshall_algorithm.py: -------------------------------------------------------------------------------- 1 | # Time O(N^3) 2 | def floyd_warshall(graph): 3 | n = len(graph) 4 | for i in range(n): 5 | for j in range(n): 6 | if graph[i][j] == -1: 7 | graph[i][j] = float('inf') 8 | if i == j: graph[i][j] = 0 9 | 10 | for k in range(n): 11 | for i in range(n): 12 | for j in range(n): 13 | graph[i][j] = min(graph[i][j], graph[i][k] + graph[k][j]) 14 | 15 | for i in range(n): 16 | for j in range(n): 17 | if graph[i][j] == float('inf'): 18 | graph[i][j] = -1 19 | 20 | return graph 21 | 22 | data = [[0,1,43],[1,0,6],[-1,-1,0]] 23 | 24 | 25 | print(floyd_warshall(data)) #[[0,1,7],[1,0,6],[-1,-1,0]] 26 | -------------------------------------------------------------------------------- /algorithms/src/graph_algorithms/kosarajus_algorithm/README.md: -------------------------------------------------------------------------------- 1 | https://www.topcoder.com/thrive/articles/kosarajus-algorithm-for-strongly-connected-components -------------------------------------------------------------------------------- /algorithms/src/graph_algorithms/single_source_shortest_path_problem/dijkstras_algorithm_sssp.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/algorithms/src/graph_algorithms/single_source_shortest_path_problem/dijkstras_algorithm_sssp.py -------------------------------------------------------------------------------- /algorithms/src/sorting_algorithms/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /algorithms/src/sorting_algorithms/bubble_sort.py: -------------------------------------------------------------------------------- 1 | # Time Complexity O(N^2) 2 | # Space Complexity O(1) 3 | 4 | def bubble_sort(array): 5 | is_sorted = False 6 | 7 | while not is_sorted: 8 | is_sorted = True 9 | for i in range(len(array) - 1): 10 | if array[i] > array[i + 1]: 11 | swap(i, i+1, array) 12 | is_sorted = False 13 | 14 | return array 15 | 16 | 17 | def swap(i, j, array): 18 | array[i], array[j] = array[j], array[i] 19 | 20 | 21 | print(bubble_sort([8, 5, 2, 9, 5, 6, 3])) 22 | print(bubble_sort([1])) 23 | print(bubble_sort([3, 1, 2])) 24 | print(bubble_sort([1, 2, 3])) -------------------------------------------------------------------------------- /algorithms/src/sorting_algorithms/insertion_sort.py: -------------------------------------------------------------------------------- 1 | # Time Complexity O(N^2) 2 | # Space Complexity O(1) 3 | 4 | def insertion_sort(array): 5 | for i in range(1, len(array)): 6 | j = i 7 | while j > 0 and array[j] < array[j - 1]: 8 | swap(j, j-1, array) 9 | j -= 1 10 | 11 | return array 12 | 13 | 14 | def swap(i, j, array): 15 | array[i], array[j] = array[j], array[i] 16 | 17 | 18 | 19 | print(insertion_sort([8, 5, 2, 9, 5, 6, 3])) 20 | print(insertion_sort([1])) 21 | print(insertion_sort([3, 1, 2])) 22 | print(insertion_sort([1, 2, 3])) -------------------------------------------------------------------------------- /algorithms/src/sorting_algorithms/selection_sort.py: -------------------------------------------------------------------------------- 1 | # Time Complexity O(N^2) 2 | # Space Complexity O(1) 3 | 4 | def selection_sort(array): 5 | current_idx = 0 6 | while current_idx < len(array) - 1: 7 | smallest_idx = current_idx 8 | for i in range(current_idx+1, len(array)): 9 | if array[smallest_idx] > array[i]: 10 | smallest_idx = i 11 | 12 | swap(current_idx, smallest_idx, array) 13 | current_idx += 1 14 | 15 | return array 16 | 17 | 18 | def swap(i, j, array): 19 | array[i], array[j] = array[j], array[i] 20 | 21 | 22 | print(selection_sort([8, 5, 2, 9, 5, 6, 3])) 23 | print(selection_sort([1])) 24 | print(selection_sort([3, 1, 2])) 25 | print(selection_sort([1, 2, 3])) -------------------------------------------------------------------------------- /assets/big-o-graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/assets/big-o-graph.png -------------------------------------------------------------------------------- /blind_75/src/arrays/buy_and_sell_stock/buy_and_sell_stock.py: -------------------------------------------------------------------------------- 1 | def max_profit(prices): 2 | left, right = 0, 1 #left represents when to buy and right represnts when to sell 3 | max_profit = 0 4 | 5 | while right < len(prices): 6 | if prices[right] > prices[left]: 7 | profit = prices[right] - prices[left] 8 | max_profit = max(max_profit, profit) 9 | else: 10 | left = right 11 | 12 | right += 1 13 | 14 | return max_profit 15 | 16 | 17 | print(max_profit([7,1,5,3,6,4])) 18 | print(max_profit([7,6,4,3,1])) -------------------------------------------------------------------------------- /blind_75/src/arrays/contains_duplicate/README.md: -------------------------------------------------------------------------------- 1 | # Contains Duplicate (Easy) 2 | 3 | Given an integer array nums, return true if any value appears at least twice in the array, 4 | and return false if every element is distinct. 5 | 6 | 7 | ### Example 1: 8 | Input: nums = [1,2,3,1] 9 | Output: true 10 | 11 | ### Example 2: 12 | Input: nums = [1,2,3,4] 13 | Output: false 14 | 15 | ### Example 3: 16 | Input: nums = [1,1,1,3,3,4,3,2,4,2] 17 | Output: true -------------------------------------------------------------------------------- /blind_75/src/arrays/maximum_subarray/README.md: -------------------------------------------------------------------------------- 1 | # Maximum Subarray (Easy) 2 | 3 | Given an integer array nums, find the contiguous subarray (containing at least one number) 4 | 5 | which has the largest sum and return its sum. A subarray is a contiguous part of an array. 6 | 7 | 8 | 9 | ### Example 1: 10 | Input: nums = [-2,1,-3,4,-1,2,1,-5,4] 11 | Output: 6 12 | Explanation: [4,-1,2,1] has the largest sum = 6. 13 | 14 | 15 | ### Example 2: 16 | Input: nums = [1] 17 | Output: 1 18 | 19 | 20 | ### Example 3: 21 | Input: nums = [5,4,-1,7,8] 22 | Output: 23 -------------------------------------------------------------------------------- /blind_75/src/arrays/product_of_array_except_self/README.md: -------------------------------------------------------------------------------- 1 | # Product of Array Except Self (Medium) 2 | 3 | Given an integer array nums, return an array answer such that answer[i] is equal 4 | 5 | to the product of all the elements of nums except nums[i]. 6 | 7 | The product of any prefix or suffix of nums is guaranteed to fit in a 32-bit integer. 8 | 9 | You must write an algorithm that runs in O(n) time and without using the division operation. 10 | 11 | 12 | 13 | ### Example 1: 14 | Input: nums = [1,2,3,4] 15 | Output: [24,12,8,6] 16 | 17 | ### Example 2: 18 | Input: nums = [-1,1,0,-3,3] 19 | Output: [0,0,9,0,0] -------------------------------------------------------------------------------- /blind_75/src/arrays/product_of_array_except_self/product_of_array_except_self.py: -------------------------------------------------------------------------------- 1 | from sys import prefix 2 | 3 | 4 | def product_except_self(nums): 5 | res = [1] * len(nums) 6 | 7 | prefix = 1 8 | for i in range(len(nums)): 9 | res[i] = prefix 10 | prefix *= nums[i] 11 | 12 | postfix = 1 13 | for i in range(len(nums)-1, -1, -1): 14 | res[i] *= postfix 15 | postfix *= nums[i] 16 | 17 | return res 18 | 19 | print(product_except_self([1,2,3,4])) 20 | print(product_except_self([-1,1,0,-3,3])) -------------------------------------------------------------------------------- /blind_75/src/arrays/two_sum/README.md: -------------------------------------------------------------------------------- 1 | # Two Sum (Easy) 2 | 3 | Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target. 4 | 5 | You may assume that each input would have exactly one solution, and you may not use the same element twice. 6 | 7 | You can return the answer in any order. 8 | 9 | ### Example 1: 10 | 11 | Input: nums = [2,7,11,15], target = 9 12 | Output: [0,1] 13 | Explanation: Because nums[0] + nums[1] == 9, we return [0, 1]. 14 | 15 | ### Example 2: 16 | 17 | Input: nums = [3,2,4], target = 6 18 | Output: [1,2] 19 | 20 | ### Example 3: 21 | 22 | Input: nums = [3,3], target = 6 23 | Output: [0,1] -------------------------------------------------------------------------------- /blind_75/src/arrays/two_sum/two_sum.py: -------------------------------------------------------------------------------- 1 | def two_sum(nums, target): 2 | num_index = {} 3 | 4 | for i, num in enumerate(nums): 5 | diff = target - num 6 | 7 | if diff in num_index: 8 | return [num_index[diff], i] 9 | 10 | num_index[num] = i 11 | 12 | return 13 | 14 | 15 | print(two_sum([2,7,11,15], 9)) 16 | print(two_sum([3,2,4], 6)) 17 | print(two_sum([3,3], 6)) -------------------------------------------------------------------------------- /blind_75/src/linkedlists/README.md: -------------------------------------------------------------------------------- 1 | ## Blind 75 LinkedList Questions 2 | 3 | `E` - Easy, `M` - Medium , `H` - Hard, 4 | 5 | * `M` [Remove Nth Node From End of List](lc_19_remove_nth_node_from_list/remove_nth_node_from_list.py) 6 | * `E` [Merge Two Sorted Lists](lc_21_merge_two_sorted_lists/merge_two_sorted_lists.py) 7 | * `E` [Merge k Sorted Lists](lc_23_merge_k_sorted_lists/merge_k_sorted_lists.py) 8 | * `E` [Linked List Cycle](lc_141_linkedlist_cycle/linkedlist_cycle.py) 9 | * `M` [Reorder List](lc_143_reorder_list/reorder_list.py) 10 | * `E` [Reverse Linked List](lc_206_reverse_linkedlist/reverse_linkedlist.py) 11 | 12 | 13 | -------------------------------------------------------------------------------- /blind_75/src/linkedlists/lc_141_linkedlist_cycle/linkedlist_cycle.py: -------------------------------------------------------------------------------- 1 | def has_cycle(head): 2 | if not head: return False 3 | 4 | slow = fast = head 5 | while fast.next and fast.next.next: 6 | slow, fast = slow.next, fast.next.next 7 | if slow == fast: 8 | return True 9 | 10 | return False -------------------------------------------------------------------------------- /blind_75/src/linkedlists/lc_19_remove_nth_node_from_list/remove_nth_node_from_list.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | class ListNode: 3 | def __init__(self, val=0, next=None): 4 | self.val = val 5 | self.next = next 6 | 7 | def removeNthFromEnd(head, n): 8 | sentinel = slow = ListNode(-1, head) 9 | fast = head 10 | 11 | while fast and n > 0: 12 | fast = fast.next 13 | n -= 1 14 | 15 | while fast: 16 | slow, fast = slow.next, fast.next 17 | 18 | slow.next = slow.next.next 19 | return sentinel.next -------------------------------------------------------------------------------- /blind_75/src/linkedlists/lc_206_reverse_linkedlist/reverse_linkedlist.py: -------------------------------------------------------------------------------- 1 | def reverse_list(head): 2 | prev, curr = None, head 3 | while curr: 4 | next_node = curr.next 5 | curr.next = prev 6 | prev, curr = curr, next_node 7 | 8 | return prev -------------------------------------------------------------------------------- /blind_75/src/linkedlists/lc_21_merge_two_sorted_lists/merge_two_sorted_lists.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | class ListNode: 3 | def __init__(self, val=0, next=None): 4 | self.val = val 5 | self.next = next 6 | 7 | # Time complexity: O(m + n) 8 | # where m and n represents the length of the two list nodes 9 | 10 | # Space complexity: O(1) 11 | def mergeTwoLists(list1, list2): 12 | sentinel = merge = ListNode(0) 13 | while list1 and list2: 14 | if list1.val < list2.val: 15 | merge.next, list1 = list1, list1.next 16 | else: 17 | merge.next, list2 = list2, list2.next 18 | merge = merge.next 19 | 20 | merge.next = list1 or list2 21 | return sentinel.next -------------------------------------------------------------------------------- /blind_75/src/trees/lc_100_same_tree/same_tree.py: -------------------------------------------------------------------------------- 1 | def same_tree(p, q): 2 | if not p and not q: return True 3 | 4 | if p and q and p.val == q.val: 5 | return (same_tree(p.left, q.left) and 6 | same_tree(p.right, q.right)) 7 | 8 | return False -------------------------------------------------------------------------------- /blind_75/src/trees/lc_102_binary_tree_level_order_traversal/binary_tree_level_order_traversal.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | def level_order_traversal(root): 4 | if not root: return [] 5 | 6 | queue, result = deque([root]), [] 7 | while queue: 8 | level_size, data = len(queue), [] 9 | for _ in range(level_size): 10 | curr = queue.popleft() 11 | data.append(curr.data) 12 | 13 | if curr.left: queue.append(curr.left) 14 | if curr.right: queue.append(curr.right) 15 | result.append(data) 16 | 17 | return result -------------------------------------------------------------------------------- /blind_75/src/trees/lc_104_max_depth_of_binary_tree/max_depth_of_binary_tree.py: -------------------------------------------------------------------------------- 1 | def max_depth_of_tree(root): 2 | if not root: return 0 3 | 4 | left = max_depth_of_tree(root.left) 5 | right = max_depth_of_tree(root.right) 6 | 7 | return max(left, right) + 1 -------------------------------------------------------------------------------- /blind_75/src/trees/lc_124_binary_tree_maximum_path_sum/binary_tree_maximum_path_sum.py: -------------------------------------------------------------------------------- 1 | def max_path_sum(root): 2 | def max_path_helper(node): 3 | nonlocal max_sum 4 | if not node: return 0 5 | 6 | left = max_path_helper(node.left) 7 | right = max_path_helper(node.right) 8 | 9 | left_sum, right_sum = node.val + left, node.val + right 10 | left_root_right_sum = left.val + node.val + right.val 11 | max_sum = max(max_sum, left_sum, right_sum, left_root_right_sum) 12 | 13 | return max(node.val, left_sum, right_sum) 14 | 15 | max_sum = float('-inf') 16 | max_path_helper(root) 17 | 18 | return max_sum -------------------------------------------------------------------------------- /blind_75/src/trees/lc_226_invert_binary_tree/invert_binary_tree.py: -------------------------------------------------------------------------------- 1 | def invert_binary_tree(root): 2 | def invert_tree_helper(node): 3 | if not node: return 4 | 5 | left = invert_tree_helper(node.left) 6 | right = invert_tree_helper(node.right) 7 | 8 | node.left, node.right = right, left 9 | return node 10 | 11 | return invert_tree_helper(root) -------------------------------------------------------------------------------- /blind_75/src/trees/lc_230_kth_smallest_in_bst/kth_smallest_in_bst.py: -------------------------------------------------------------------------------- 1 | def kth_smallest_in_bst(root, k): 2 | def kth_smallest_helper(node): 3 | nonlocal i, kth_smallest, found 4 | if not node: return 5 | if found: return 6 | 7 | kth_smallest_helper(node.left) 8 | i += 1 9 | 10 | if i == k: 11 | kth_smallest, found = node.val, True 12 | return True 13 | 14 | kth_smallest_helper(node.right) 15 | 16 | i, kth_smallest, found = 0, None, False 17 | kth_smallest_helper(root) 18 | 19 | return kth_smallest -------------------------------------------------------------------------------- /blind_75/src/trees/lc_235_lca_of_binary_search_tree/lca_bst.py: -------------------------------------------------------------------------------- 1 | def lca_bst(root, p, q): 2 | if not root: return 3 | if p.val < root.val and q.val < root.val: 4 | return lca_bst(root.left, p, q) 5 | elif p.val > root.val and q.val > root.val: 6 | return lca_bst(root.right, p, q) 7 | else: 8 | return root -------------------------------------------------------------------------------- /blind_75/src/trees/lc_572_subtree_of_another_tree/subtree_of_another_tree.py: -------------------------------------------------------------------------------- 1 | def subtree_of_another_tree(root, subroot): 2 | if not subroot: return True 3 | if not root: return False 4 | 5 | if same_tree(root, subroot): 6 | return True 7 | 8 | return (subtree_of_another_tree(root.left, subroot) or 9 | subtree_of_another_tree(root.right, subroot)) 10 | 11 | 12 | def same_tree(p, q): 13 | if not p and not q: return True 14 | 15 | if p and q and p.val == q.val: 16 | return (same_tree(p.left, p.left) and 17 | same_tree(p.right, q.right)) 18 | return False -------------------------------------------------------------------------------- /blind_75/src/trees/lc_98_validate_binary_search_tree/validate_binary_search_tree.py: -------------------------------------------------------------------------------- 1 | def valid_bst(root): 2 | def valid_bst_helper(node, lower_bound, upper_bound): 3 | if node is None: return True 4 | 5 | if not (lower_bound < node.val < upper_bound): 6 | return False 7 | 8 | return (valid_bst_helper(node.left, lower_bound, node.val) and 9 | valid_bst_helper(node.right, node.val, upper_bound)) 10 | 11 | return valid_bst_helper(root, float('-inf'), float('inf')) -------------------------------------------------------------------------------- /data-structures/assets/array-representation.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/array-representation.jpeg -------------------------------------------------------------------------------- /data-structures/assets/circular_doubly_linkedlist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/circular_doubly_linkedlist.png -------------------------------------------------------------------------------- /data-structures/assets/circular_linkedlist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/circular_linkedlist.png -------------------------------------------------------------------------------- /data-structures/assets/circular_queue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/circular_queue.png -------------------------------------------------------------------------------- /data-structures/assets/collision-resolution.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/collision-resolution.jpeg -------------------------------------------------------------------------------- /data-structures/assets/doubly-linked-list.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/doubly-linked-list.jpeg -------------------------------------------------------------------------------- /data-structures/assets/doubly_linkedlist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/doubly_linkedlist.png -------------------------------------------------------------------------------- /data-structures/assets/graph.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/graph.jpeg -------------------------------------------------------------------------------- /data-structures/assets/hash-table.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/hash-table.jpeg -------------------------------------------------------------------------------- /data-structures/assets/linked-list.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/linked-list.jpeg -------------------------------------------------------------------------------- /data-structures/assets/linkedList_array_comparisons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/linkedList_array_comparisons.png -------------------------------------------------------------------------------- /data-structures/assets/linkedlist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/linkedlist.png -------------------------------------------------------------------------------- /data-structures/assets/max-heap.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/max-heap.jpeg -------------------------------------------------------------------------------- /data-structures/assets/min-heap.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/min-heap.jpeg -------------------------------------------------------------------------------- /data-structures/assets/queue.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/queue.jpeg -------------------------------------------------------------------------------- /data-structures/assets/queue_comparisons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/queue_comparisons.png -------------------------------------------------------------------------------- /data-structures/assets/queue_linkedlist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/queue_linkedlist.png -------------------------------------------------------------------------------- /data-structures/assets/queue_with_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/queue_with_list.png -------------------------------------------------------------------------------- /data-structures/assets/stack_linkedlist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/stack_linkedlist.png -------------------------------------------------------------------------------- /data-structures/assets/stack_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/stack_list.png -------------------------------------------------------------------------------- /data-structures/assets/time_complexity_linkedList.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/time_complexity_linkedList.png -------------------------------------------------------------------------------- /data-structures/assets/trie.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/data-structures/assets/trie.jpeg -------------------------------------------------------------------------------- /data-structures/src/circular-doubly-linked-list/README.md: -------------------------------------------------------------------------------- 1 | ## Time and Space Complexity of Circular Doubly Linked List 2 | 3 | ![Circualr Singly Linked List](./../../assets/circular_doubly_linkedlist.png) -------------------------------------------------------------------------------- /data-structures/src/circular-linked-list/README.md: -------------------------------------------------------------------------------- 1 | ## Time and Space Complexity of Circular Singly Linked List 2 | 3 | ![Circualr Singly Linked List](./../../assets/circular_linkedlist.png) -------------------------------------------------------------------------------- /data-structures/src/queue/circular_queue/README.md: -------------------------------------------------------------------------------- 1 | ## Time and Space Complexities of Circular Queue operations 2 | 3 | ![Circular Queue](./../../../assets/circular_queue.png) -------------------------------------------------------------------------------- /data-structures/src/queue/queue_using_librarys/Deque.py: -------------------------------------------------------------------------------- 1 | # How to use collections.deque as a FIFO queue: 2 | 3 | from collections import deque 4 | 5 | customQueue = deque(maxlen=3) 6 | print(customQueue) 7 | 8 | customQueue.append(1) 9 | customQueue.append(2) 10 | customQueue.append(3) 11 | customQueue.append(4) 12 | print(customQueue) 13 | print(customQueue.clear()) 14 | print(customQueue) -------------------------------------------------------------------------------- /data-structures/src/queue/queue_using_librarys/MultiprocessingQueue.py: -------------------------------------------------------------------------------- 1 | # How to use multiprocessing.Queue as a FIFO queue: 2 | 3 | from multiprocessing import Queue 4 | 5 | customQueue = Queue(maxsize= 3) 6 | customQueue.put(1) 7 | print(customQueue.get()) -------------------------------------------------------------------------------- /data-structures/src/queue/queue_using_librarys/QueueModule.py: -------------------------------------------------------------------------------- 1 | import queue as q 2 | 3 | customQueue = q.Queue(maxsize=3) 4 | print(customQueue.empty()) 5 | customQueue.put(1) 6 | customQueue.put(2) 7 | customQueue.put(3) 8 | print(customQueue.full()) 9 | print(customQueue.get()) 10 | print(customQueue.qsize()) 11 | -------------------------------------------------------------------------------- /data-structures/src/queue/queue_with_linkedlist/README.md: -------------------------------------------------------------------------------- 1 | ## Time and Space Complexities of Queue operations using Linked list 2 | 3 | ![Queue With linkedlist](./../../../assets/queue_linkedlist.png) -------------------------------------------------------------------------------- /data-structures/src/queue/queue_with_list/README.md: -------------------------------------------------------------------------------- 1 | ## Time and Space Complexities of Queue operations using a python list 2 | 3 | ![Queue With list](./../../../assets/queue_with_list.png) -------------------------------------------------------------------------------- /leetcode/src/array&hashing/README.md: -------------------------------------------------------------------------------- 1 | ## Leetcode Array Questions 2 | 3 | `E` - Easy, `M` - Medium , `H` - Hard, 4 | 5 | * `M` [Maximum Product Subarray](lc_152_max_product_subarray/max_product_subarray.py) 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /leetcode/src/array&hashing/lc_152_max_product_subarray/max_product_brute_force.py: -------------------------------------------------------------------------------- 1 | def max_product(nums): 2 | n = len(nums) 3 | if(n == 0): return 0 4 | 5 | result = float('-inf') 6 | for i in range(n): 7 | curr_val = nums[i] 8 | result = max(result, curr_val) 9 | sub_product = 1 10 | for j in range(i+1, n): 11 | sub_product *= nums[j] 12 | result = max(result, sub_product * curr_val) 13 | 14 | return result 15 | 16 | 17 | print(max_product([2,3,-2,4])) # 6 18 | print(max_product([-2,0,-1])) # 0 19 | print(max_product([-2,0,5])) # 5 20 | print(max_product([1,2,-3,0,-4,-5])) # 20 21 | print(max_product([1,2,3,4,5,0])) # 120 22 | print(max_product([2, -1, 0, 3, 1, -1])) # 3 -------------------------------------------------------------------------------- /leetcode/src/array&hashing/lc_152_max_product_subarray/max_product_subarray.py: -------------------------------------------------------------------------------- 1 | def max_product(nums): 2 | n, result, prefix, suffix = len(nums), float('-inf'), 1, 1 3 | 4 | for i in range(n): 5 | if prefix == 0: prefix = 1 6 | if suffix == 0: suffix = 1 7 | 8 | prefix *= nums[i] 9 | suffix *= nums[n-i-1] 10 | result = max(result, max(prefix, suffix)) 11 | 12 | return result 13 | 14 | 15 | print(max_product([2,3,-2,4])) # 6 16 | print(max_product([-2,0,-1])) # 0 17 | print(max_product([-2,0,5])) # 5 18 | print(max_product([1,2,-3,0,-4,-5])) # 20 19 | print(max_product([1,2,3,4,5,0])) # 120 20 | print(max_product([2, -1, 0, 3, 1, -1])) # 3 -------------------------------------------------------------------------------- /leetcode/src/array&hashing/lc_1_two_sum/two_sum.py: -------------------------------------------------------------------------------- 1 | def two_sum(nums, target): 2 | num_idx = {} 3 | for i in range(len(nums)): 4 | diff = target - nums[i] 5 | if diff in num_idx: 6 | return [num_idx[diff], i] 7 | 8 | num_idx[nums[i]] = i 9 | 10 | return [] 11 | 12 | 13 | print(two_sum([2,7,11,15], 9)) 14 | print(two_sum([3,2,4], 6)) 15 | print(two_sum([3,3], 6)) -------------------------------------------------------------------------------- /leetcode/src/array&hashing/lc_217_contains_duplicate/README.md: -------------------------------------------------------------------------------- 1 | # [LC 217. Contains Duplicate - Easy](https://leetcode.com/problems/contains-duplicate/description/) 2 | 3 | Given an integer array nums, return true if any value appears at least twice in the array, and return false if every element is distinct. 4 | 5 | 6 | ### Example 1 7 | ``` 8 | Input: nums = [1,2,3,1] 9 | Output: true 10 | ``` 11 | 12 | ### Example 2 13 | ``` 14 | Input: nums = [1,2,3,4] 15 | Output: false 16 | ``` 17 | 18 | ### Example 3 19 | ``` 20 | Input: nums = [1,1,1,3,3,4,3,2,4,2] 21 | Output: true 22 | ``` 23 | 24 | ### Constraints: 25 | 26 | - 1 <= nums.length <= 10^5 27 | - -10^9 <= nums[i] <= 10^9 -------------------------------------------------------------------------------- /leetcode/src/array&hashing/lc_217_contains_duplicate/contains_duplicate.py: -------------------------------------------------------------------------------- 1 | 2 | # Time: O(n) 3 | # Space: O(n) 4 | def containsDuplicate(nums) -> bool: 5 | hash_set = set() 6 | for val in nums: 7 | if val in hash_set: 8 | return True 9 | hash_set.add(val) 10 | 11 | return False 12 | 13 | 14 | # Time: O(n) 15 | # Space: O(n) 16 | def containsDuplicate2(nums) -> bool: 17 | num_freq = {} 18 | for val in nums: 19 | if val in num_freq: 20 | return True 21 | num_freq[val] = 1 22 | 23 | return False -------------------------------------------------------------------------------- /leetcode/src/array&hashing/lc_238_product_of_array_except_itself/product_of_array.py: -------------------------------------------------------------------------------- 1 | def productExceptSelf(nums): 2 | result = [1] * len(nums) 3 | prefix = 1 4 | for i in range(len(nums)): 5 | result[i] = prefix 6 | prefix *= nums[i] 7 | 8 | postfix = 1 9 | for i in range(len(nums) - 1, -1, -1): 10 | result[i] *= postfix 11 | postfix *= nums[i] 12 | 13 | return result -------------------------------------------------------------------------------- /leetcode/src/backtracking/README.md: -------------------------------------------------------------------------------- 1 | ## Leetcode Backtracking Questions 2 | 3 | `E` - Easy, `M` - Medium , `H` - Hard, 4 | 5 | * `M` [Combination Sum](lc_39_combination_sum_I/combination_sum.py) 6 | * `M` [Combination Sum II](lc_40_combination_sum_II/combination_sum.py) 7 | * `M` [Subsets I](lc_78_subsets/subsets.py) 8 | * `M` [Letter Case Permutation](lc_784_letter_code_permutation/letter_code_permutation.py) -------------------------------------------------------------------------------- /leetcode/src/backtracking/lc_115_distinct_subsequences/distinct_subs.py: -------------------------------------------------------------------------------- 1 | def numDistinct(s, t): 2 | def count(i, chars): 3 | if len(s) == i: 4 | result = "".join(chars) 5 | if result == t: 6 | return 1 7 | return 0 8 | 9 | chars.append(s[i]) 10 | i += 1 11 | left = count(i, chars) 12 | 13 | chars.pop() 14 | right = count(i, chars) 15 | 16 | return left + right 17 | 18 | return count(0, []) 19 | 20 | print(numDistinct(s = "rabbbit", t = "rabbit")) #3 21 | print(numDistinct(s = "babgbag", t = "bag")) #5 -------------------------------------------------------------------------------- /leetcode/src/backtracking/lc_131_palindrom_partitioning/README.md: -------------------------------------------------------------------------------- 1 | # [LC 131. Palindrome Partitioning - Medium](https://leetcode.com/problems/palindrome-partitioning/) 2 | 3 | Given a string s, partition s such that every substring of the partition is a palindrome. 4 | 5 | Return all possible palindrome partitioning of s. 6 | 7 | 8 | ### Example 1 9 | 10 | ``` 11 | Input: s = "aab" 12 | Output: [["a","a","b"],["aa","b"]] 13 | ``` 14 | 15 | ### Example 2 16 | 17 | ``` 18 | Input: s = "a" 19 | Output: [["a"]] 20 | ``` 21 | 22 | 23 | ### Constraints: 24 | 25 | - 1 <= s.length <= 16 26 | - s contains only lowercase English letters. -------------------------------------------------------------------------------- /leetcode/src/backtracking/lc_78_subsets/README.md: -------------------------------------------------------------------------------- 1 | # [LC 78. Subsets- Medium](https://leetcode.com/problems/subsets/description/) 2 | 3 | Given an integer array nums of unique elements, return all possible subsets (the power set). 4 | 5 | The solution set must not contain duplicate subsets. Return the solution in any order. 6 | 7 | 8 | 9 | ### Example 1 10 | 11 | ``` 12 | Input: nums = [1,2,3] 13 | Output: [[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]] 14 | ``` 15 | 16 | ### Example 2 17 | 18 | ``` 19 | Input: nums = [0] 20 | Output: [[],[0]] 21 | ``` 22 | 23 | 24 | ### Constraints: 25 | 26 | - 1 <= nums.length <= 10 27 | - -10 <= nums[i] <= 10 28 | - All the numbers of nums are unique. -------------------------------------------------------------------------------- /leetcode/src/backtracking/lc_90_subsets_II/README.md: -------------------------------------------------------------------------------- 1 | # [LC 90. Subsets II - Medium](https://leetcode.com/problems/subsets/description/) 2 | 3 | Given an integer array nums that may contain duplicates, return all possible subsets (the power set). 4 | 5 | The solution set must not contain duplicate subsets. Return the solution in any order. 6 | 7 | 8 | 9 | ### Example 1 10 | 11 | ``` 12 | Input: nums = [1,2,2] 13 | Output: [[],[1],[1,2],[1,2,2],[2],[2,2]] 14 | ``` 15 | 16 | ### Example 2 17 | 18 | ``` 19 | Input: nums = [0] 20 | Output: [[],[0]] 21 | ``` 22 | 23 | 24 | ### Constraints: 25 | 26 | - 1 <= nums.length <= 10 27 | - -10 <= nums[i] <= 10 -------------------------------------------------------------------------------- /leetcode/src/backtracking/lc_90_subsets_II/subsets.py: -------------------------------------------------------------------------------- 1 | 2 | # Time :O(nlog n + 2^n * n) 3 | # Space: O(2^n * k) 4 | # Auxilliary Space of Recursion: O(n) 5 | 6 | def subsets(nums): 7 | result = [] 8 | nums.sort() 9 | subset_helper(nums, result, [], 0) 10 | return result 11 | 12 | def subset_helper(nums, result, path, idx): 13 | 14 | result.append(list(path)) 15 | 16 | for i in range(idx, len(nums)): 17 | if i > idx and nums[i] == nums[i-1]: continue 18 | path.append(nums[i]) 19 | subset_helper(nums, result, path, i+1) 20 | 21 | path.pop() 22 | 23 | 24 | print(subsets([1])) 25 | print(subsets([1, 1])) 26 | print(subsets([1,1,2])) 27 | print(subsets([1, 2, 3])) 28 | print(subsets([1, 2, 3, 4])) 29 | -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_101_symmetric_tree/README.md: -------------------------------------------------------------------------------- 1 | # [LC 101. Symmetric Tree - Easy](https://leetcode.com/problems/symmetric-tree//description/) 2 | 3 | Given the root of a binary tree, check whether it is a mirror of itself (i.e., symmetric around its center). 4 | 5 | ### Example 1 6 | 7 | ![Symmetric Tree Example 1](https://assets.leetcode.com/uploads/2021/02/19/symtree1.jpg) 8 | 9 | 10 | ``` 11 | Input: root = [1,2,2,3,4,4,3] 12 | Output: true 13 | ``` 14 | 15 | ### Example 2 16 | 17 | ![Symmetric Tree Example 2](https://assets.leetcode.com/uploads/2021/02/19/symtree2.jpg) 18 | 19 | ``` 20 | Input: root = [1,2,2,null,3,null,3] 21 | Output: false 22 | ``` 23 | 24 | 25 | ### Constraints: 26 | 27 | - The number of nodes in the tree is in the range [1, 1000]. 28 | - -100 <= Node.val <= 100 -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_102_binary_tree_level_order_traversal/binary_tree_level_order_traversal.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | def level_order_traversal(root): 4 | if not root: 5 | return [] 6 | 7 | result = [] 8 | queue = deque([root]) 9 | while queue: 10 | level_size, data = len(queue), [] 11 | for _ in range(level_size): 12 | curr_node = queue.popleft() 13 | data.append(curr_node.val) 14 | if curr_node.left: 15 | queue.append(curr_node.left) 16 | if curr_node.right: 17 | queue.append(curr_node.right) 18 | 19 | result.append(data) 20 | 21 | return result -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_104_max_depth_of_binary_tree/max_depth_of_binary_tree.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, val): 3 | self.val = val 4 | self.left = self.right = None 5 | 6 | 7 | def max_depth(root): 8 | if root is None: 9 | return 0 10 | 11 | left_result = max_depth(root.left) 12 | right_result = max_depth(root.right) 13 | 14 | return max(left_result, right_result) + 1 15 | 16 | 17 | node_A = Node('A') 18 | node_B = Node('B') 19 | node_C = Node('C') 20 | node_D = Node('D') 21 | node_E = Node('E') 22 | node_F = Node('F') 23 | node_G = Node('G') 24 | 25 | node_A.left, node_A.right = node_B, node_C 26 | node_B.left, node_B.right = node_D, node_E 27 | node_C.left, node_C.right = node_F, node_G 28 | 29 | 30 | print(max_depth(node_A)) #3 -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_107_binary_tree_level_order_traversal_II/binary_tree_level_order_traversal.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | def level_order_bottom(root): 4 | if not root: 5 | return [] 6 | 7 | result = deque() 8 | queue = deque([root]) 9 | while queue: 10 | level_size, level_data = len(queue), [] 11 | for _ in range(level_size): 12 | curr_node = queue.popleft() 13 | level_data.append(curr_node.val) 14 | 15 | if curr_node.left: 16 | queue.append(curr_node.left) 17 | 18 | if curr_node.right: 19 | queue.append(curr_node.right) 20 | 21 | result.appendleft(level_data) 22 | 23 | return result -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_113_path_sum_II/path_sum.py: -------------------------------------------------------------------------------- 1 | def path_sum(root, target_sum): 2 | def path_sum_helper(node, path, target): 3 | if node is None: return 4 | 5 | path.append(node.val) 6 | current_target = target - node.val 7 | if node.left is None and node.right is None and current_target == 0: 8 | result.append(list(path)) 9 | else: 10 | path_sum_helper(node.left, path, current_target) 11 | path_sum_helper(node.right, path, current_target) 12 | 13 | path.pop() 14 | 15 | result = [] 16 | path_sum_helper(root, [], target_sum) 17 | 18 | return result -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_124_binary_tree_maximum_path_sum/binary_tree_maximum_path_sum.py: -------------------------------------------------------------------------------- 1 | def maxPathSum(root): 2 | def maxPathSumHelper(node): 3 | nonlocal max_sum 4 | if node is None: return 0 5 | 6 | left = maxPathSumHelper(node.left) 7 | right = maxPathSumHelper(node.right) 8 | 9 | left_tree_sum = left + node.val 10 | right_tree_sum = right + node.val 11 | left_right_tree_sum = left + right + node.val 12 | max_sum = max(max_sum, node.val, left_tree_sum, right_tree_sum, left_right_tree_sum) 13 | 14 | 15 | return max(node.val, left_tree_sum, right_tree_sum) 16 | 17 | max_sum = float('-inf') 18 | maxPathSumHelper(root) 19 | 20 | return max_sum -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_129_sum_root_to_leaf_numbers/sum_root_to_leaf_numbers.py: -------------------------------------------------------------------------------- 1 | def sum_numbers(root): 2 | def sum_numbers_helper(node, curr_sum): 3 | if node is None: return 0 4 | 5 | curr_sum = curr_sum * 10 + node.val 6 | if node.left is None and node.right is None: 7 | return curr_sum 8 | 9 | return sum_numbers_helper(node.left, curr_sum) + sum_numbers_helper(node.right, curr_sum) 10 | 11 | return sum_numbers_helper(root, 0) -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_144_preorder_traversal/README.md: -------------------------------------------------------------------------------- 1 | # [LC 144. Binary Tree Preorder Traversal- Easy](https://leetcode.com/problems/binary-tree-preorder-traversal/description/) 2 | 3 | Given the root of a binary tree, return the preorder traversal of its nodes' values. 4 | 5 | ### Example 1 6 | 7 | ![PreOrder Traversal Example 1](https://assets.leetcode.com/uploads/2020/09/15/inorder_1.jpg) 8 | 9 | 10 | ``` 11 | Input: root = [1,null,2,3] 12 | Output: [1,2,3] 13 | ``` 14 | 15 | ### Example 2 16 | 17 | ``` 18 | Input: root = [] 19 | Output: [] 20 | ``` 21 | 22 | ### Example 3 23 | 24 | ``` 25 | Input: root = [1] 26 | Output: [1] 27 | ``` 28 | 29 | ### Constraints: 30 | 31 | - The number of nodes in the tree is in the range [0, 100]. 32 | - -100 <= Node.val <= 100 -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_145_postorder_traversal/README.md: -------------------------------------------------------------------------------- 1 | # [LC 145. Binary Tree Postorder Traversal- Easy](https://leetcode.com/problems/binary-tree-postorder-traversal/description/) 2 | 3 | Given the root of a binary tree, return the postorder traversal of its nodes' values. 4 | 5 | ### Example 1 6 | 7 | ![PreOrder Traversal Example 1](https://assets.leetcode.com/uploads/2020/09/15/inorder_1.jpg) 8 | 9 | 10 | ``` 11 | Input: root = [1,null,2,3] 12 | Output: [3,2,1] 13 | ``` 14 | 15 | ### Example 2 16 | 17 | ``` 18 | Input: root = [] 19 | Output: [] 20 | ``` 21 | 22 | ### Example 3 23 | 24 | ``` 25 | Input: root = [1] 26 | Output: [1] 27 | ``` 28 | 29 | ### Constraints: 30 | 31 | - The number of nodes in the tree is in the range [0, 100]. 32 | - -100 <= Node.val <= 100 -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_222_count_complete_tree_nodes/count_complete_tree_nodes.py: -------------------------------------------------------------------------------- 1 | def countNodes(root): 2 | def countNodesHelper(node): 3 | nonlocal count 4 | if node is None: return 5 | 6 | countNodesHelper(node.left) 7 | count += 1 8 | countNodesHelper(node.right) 9 | 10 | count = 0 11 | if root: 12 | countNodesHelper(root) 13 | 14 | return count -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_226_invert_binary_tree/invert_binary_tree.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, val, left=None, right=None): 3 | self.val = val 4 | self.left, self.right = left, right 5 | 6 | 7 | # Best Case - Time O(n) | Space O(h) 8 | # Worst Case - Time O(n) | Space O(n) 9 | def invert_binary_tree(root): 10 | def invert_binary_tree_helper(node): 11 | if node is None: 12 | return 13 | 14 | left_result = invert_binary_tree_helper(node.left) 15 | right_result = invert_binary_tree_helper(node.right) 16 | 17 | #swap nodes after left and right subtrees traversal 18 | node.left, node.right = right_result, left_result 19 | 20 | return node 21 | 22 | return invert_binary_tree_helper(root) -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_230_kth_smallest_in_bst/kth_smallest_in_bst.py: -------------------------------------------------------------------------------- 1 | def kthSmallest(root, k): 2 | def kthSmallestBstHelper(node): 3 | nonlocal kth_smallest, count, found 4 | if node is None: return 5 | if found: return 6 | 7 | kthSmallestBstHelper(node.left) 8 | 9 | count += 1 10 | if count == k: 11 | kth_smallest, found = node.val, True 12 | return 13 | 14 | kthSmallestBstHelper(node.right) 15 | 16 | kth_smallest, count, found = None, 0, False 17 | kthSmallestBstHelper(root) 18 | return kth_smallest -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_235_lca_of_binary_search_tree/lca_bst.py: -------------------------------------------------------------------------------- 1 | class TreeNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.left = None 5 | self.right = None 6 | 7 | def lca_bst(root, p, q): 8 | def lca_helper(node): 9 | if node is None: 10 | return None 11 | 12 | if p.val < node.val and q.val < node.val: 13 | return lca_bst(node.left, p, q) 14 | elif p.val > node.val and q.val > node.val: 15 | return lca_bst(node.right, p, q) 16 | else: 17 | return node 18 | 19 | return lca_helper(root) -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_236_lowest_common_ancestor_of_binary_tree/lowest_common_ancestor_of_binary_tree.py: -------------------------------------------------------------------------------- 1 | from collections import namedtuple 2 | 3 | 4 | def lca(root, p, q): 5 | Data = namedtuple('Data', ['ancestor', 'count']) 6 | def lca_helper(node): 7 | if node is None: return Data(None, 0) 8 | 9 | left = lca_helper(node.left) 10 | if left.count == 2: 11 | return left 12 | 13 | right = lca_helper(node.right) 14 | if right.count == 2: 15 | return right 16 | 17 | num_target_nodes = left.count + right.count + int(node is p) + int(node is q) 18 | return Data(node if num_target_nodes == 2 else None, num_target_nodes) 19 | 20 | return lca_helper(root).ancestor -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_257_binary_tree_paths/README.md: -------------------------------------------------------------------------------- 1 | # [LC 257. Binary Tree Paths - Easy](https://leetcode.com/problems/binary-tree-paths/description/) 2 | 3 | Given the root of a binary tree, return all root-to-leaf paths in any order. 4 | 5 | A leaf is a node with no children. 6 | 7 | ### Example 1 8 | 9 | ![Binary Tree Paths Example 1](https://assets.leetcode.com/uploads/2021/03/12/paths-tree.jpg) 10 | 11 | 12 | ``` 13 | Input: root = [1,2,3,null,5] 14 | Output: ["1->2->5","1->3"] 15 | ``` 16 | 17 | ### Example 2 18 | 19 | ``` 20 | Input: root = [1] 21 | Output: ["1"] 22 | ``` 23 | 24 | 25 | ### Constraints: 26 | 27 | - The number of nodes in the tree is in the range [1, 100]. 28 | - -100 <= Node.val <= 100 -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_337_house_robber_III/house_robber.py: -------------------------------------------------------------------------------- 1 | def rob(root): 2 | def robHelper(node): 3 | if not node: return [0,0] 4 | 5 | left = robHelper(node.left) 6 | right = robHelper(node.right) 7 | 8 | with_root = node.val + left[1] + right[1] 9 | without_root = max(left) + max(right) 10 | 11 | return [with_root, without_root] 12 | 13 | return max(robHelper(root)) -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_437_path_sum_III/path_sum.py: -------------------------------------------------------------------------------- 1 | def path_sum(root, target_sum): 2 | def path_sum_helper(node, path): 3 | nonlocal count 4 | if node is None: return 5 | 6 | path.append(node.val) 7 | total_sum = 0 8 | for i in range(len(path) - 1, -1, -1): 9 | total_sum += path[i] 10 | if total_sum == target_sum: 11 | count += 1 12 | 13 | path_sum_helper(node.left, path) 14 | path_sum_helper(node.right, path) 15 | 16 | path.pop() 17 | 18 | count = 0 19 | path_sum_helper(root, []) 20 | return count -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_513_find_bottom_left_tree_value/find_bottom_left_tree_value.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | def findBottomLeftValue(root): 4 | queue = deque([root]) 5 | 6 | left_most_val = None 7 | while queue: 8 | level_size = len(queue) 9 | for i in range(level_size): 10 | curr_node = queue.popleft() 11 | if i == 0: 12 | left_most_val = curr_node.val 13 | 14 | if curr_node.left: 15 | queue.append(curr_node.left) 16 | if curr_node.right: 17 | queue.append(curr_node.right) 18 | 19 | return left_most_val -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_515_find_largest_value_in_each_tree_row/README.md: -------------------------------------------------------------------------------- 1 | # [LC 515. Find Largest Value in Each Tree Row - Medium](https://leetcode.com/problems/convert-bst-to-greater-tree/description/) 2 | 3 | Given the root of a binary tree, return an array of the largest value in each row of the tree (0-indexed). 4 | 5 | ### Example 1 6 | 7 | ![Find Largest Value in Each Tree Row Example 1](https://assets.leetcode.com/uploads/2020/08/21/largest_e1.jpg) 8 | 9 | ``` 10 | Input: root = [1,3,2,5,3,null,9] 11 | Output: [1,3,9] 12 | ``` 13 | 14 | ### Example 2 15 | 16 | ``` 17 | Input: root = [1,2,3] 18 | Output: [1,3] 19 | ``` 20 | 21 | 22 | ### Constraints: 23 | 24 | - The number of nodes in the tree will be in the range [0, 104]. 25 | - -2^31 <= Node.val <= 2^31 - 1 -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_515_find_largest_value_in_each_tree_row/find_largest_value_in_each_tree_row.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | def largestValues(root): 4 | if not root: 5 | return [] 6 | 7 | queue, result = deque([root]), [] 8 | while queue: 9 | level_size, max_node_val = len(queue), float('-inf') 10 | for _ in range(level_size): 11 | curr_node = queue.popleft() 12 | max_node_val = max(max_node_val, curr_node.val) 13 | 14 | if curr_node.left: 15 | queue.append(curr_node.left) 16 | if curr_node.right: 17 | queue.append(curr_node.right) 18 | result.append(max_node_val) 19 | return result -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_538_convert_bst_to_greater_tree/convert_bst_to_greater_tree.py: -------------------------------------------------------------------------------- 1 | def convertBST(root): 2 | def convertBstHelper(node): 3 | nonlocal running_sum 4 | if node is None: return 5 | 6 | convertBstHelper(node.right) 7 | 8 | node.val += running_sum 9 | running_sum = node.val 10 | 11 | convertBstHelper(node.left) 12 | 13 | running_sum = 0 14 | convertBstHelper(root) 15 | return root -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_543_diameter_of_a_tree/tree_diameter.py: -------------------------------------------------------------------------------- 1 | class TreeNode: 2 | def __init__(self, val=0, left=None, right=None): 3 | self.val = val 4 | self.left = left 5 | self.right = right 6 | 7 | 8 | def tree_diameter(root): 9 | def tree_diameter_helper(node): 10 | nonlocal diameter 11 | if node is None: 12 | return 0 13 | 14 | left = tree_diameter_helper(node.left) 15 | right = tree_diameter_helper(node.right) 16 | 17 | diameter = max(diameter, left + right) 18 | 19 | return max(left, right) + 1 20 | 21 | diameter = 0 22 | tree_diameter_helper(root) 23 | 24 | return diameter -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_572_subtree_of_another_tree/subtree_of_another_tree.py: -------------------------------------------------------------------------------- 1 | # Time O(mn) 2 | def is_subtree(root, sub_root): 3 | if not sub_root: return True 4 | if not root: return False 5 | 6 | if is_same_tree(root, sub_root): 7 | return True 8 | 9 | return is_subtree(root.left, sub_root) or is_subtree(root.right, sub_root) 10 | 11 | def is_same_tree(s, q): 12 | if not s and not q: return True 13 | if s and q and s.val == q.val: 14 | return (is_same_tree(s.left, q.left) and is_same_tree(s.right, q.right)) 15 | 16 | return False -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_606_construct_string_from_tree/construct_string_from_tree.py: -------------------------------------------------------------------------------- 1 | class TreeNode: 2 | def __init__(self, val=0, left=None, right=None): 3 | self.val = val 4 | self.left = left 5 | self.right = right 6 | 7 | def treeStr(root): 8 | def treeStrHelper(node): 9 | result = str(node.val) 10 | 11 | if node.left: 12 | result += "(" + treeStrHelper(node.left) + ")" 13 | 14 | if node.right: 15 | if not node.left: 16 | result += "()" 17 | 18 | result += "(" + treeStrHelper(node.right) + ")" 19 | 20 | return result 21 | 22 | return treeStrHelper(root) -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_637_average_of_levels_in_binary_tree/average_of_levels_in_binary_tree.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | def average_of_levels(root): 4 | queue = deque([root]) 5 | result = [] 6 | 7 | while queue: 8 | level_size = len(queue) 9 | total_sum = 0 10 | 11 | for _ in range(level_size): 12 | curr_node = queue.popleft() 13 | 14 | total_sum += curr_node.val 15 | if curr_node.left: 16 | queue.append(curr_node.left) 17 | 18 | if curr_node.right: 19 | queue.append(curr_node.right) 20 | 21 | result.append(total_sum / level_size) 22 | 23 | return result -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_652_find_duplicate_subtrees/find_duplicate_subtrees.py: -------------------------------------------------------------------------------- 1 | def findDuplicateSubtrees(root): 2 | def findDups(node): 3 | if node is None: return "#" 4 | 5 | path = [str(node.val)] 6 | path.append(findDups(node.left)) 7 | path.append(findDups(node.right)) 8 | 9 | path = ",".join(path) 10 | if path in tree_map: 11 | tree_map[path] += 1 12 | if tree_map[path] == 2: 13 | result.append(node) 14 | else: 15 | tree_map[path] = 1 16 | 17 | return path 18 | 19 | result, tree_map = [], {} 20 | findDups(root) 21 | 22 | return result -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_653_two_sum_IV/two_sum.py: -------------------------------------------------------------------------------- 1 | 2 | def two_sum_bst(root, target): 3 | def two_sum_helper(node): 4 | if node is None: 5 | return False 6 | 7 | diff = target - node.val 8 | if diff in value_map: 9 | return True 10 | 11 | value_map[node.val] = diff 12 | 13 | left = two_sum_helper(node.left) 14 | if left: 15 | return left 16 | 17 | right = two_sum_helper(node.right) 18 | if right: 19 | return right 20 | 21 | return False 22 | 23 | 24 | value_map = {} 25 | return two_sum_helper(root) -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_662_maximum_width_of_binary_tree/maximum_width_of_binary_tree.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | def widthOfBinaryTree(root): 4 | if not root: return 0 5 | 6 | queue = deque([(root, 1)]) 7 | max_width = 0 8 | while queue: 9 | level_width = queue[-1][1] - queue[0][1] + 1 10 | max_width = max(max_width, level_width) 11 | level_size = len(queue) 12 | for _ in range(level_size): 13 | curr_node, idx = queue.popleft() 14 | 15 | if curr_node.left: 16 | queue.append((curr_node.left, 2 * idx)) 17 | 18 | if curr_node.right: 19 | queue.append((curr_node.right, 2 * idx + 1)) 20 | 21 | return max_width -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_669_trim_a_binary_search_tree/trim_a_binary_search_tree.py: -------------------------------------------------------------------------------- 1 | def trimBST(root, low, high): 2 | def trim(node): 3 | if not node: 4 | return None 5 | elif node.val > high: 6 | return trim(node.left) 7 | elif node.val < low: 8 | return trim(node.right) 9 | else: 10 | node.left = trim(node.left) 11 | node.right = trim(node.right) 12 | 13 | return node 14 | 15 | return trim(root) -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_671_second_minimum_node_in_binary_tree/second_minimum_node_in_binary_tree.py: -------------------------------------------------------------------------------- 1 | # Time O(n) | Space O(h) 2 | def find_second_min_val(root): 3 | def find_second_min_val_helper(node): 4 | nonlocal min_val, second_min_val 5 | if node is None: return 6 | 7 | if node.val <= min_val: 8 | min_val = node.val 9 | elif node.val <= second_min_val: 10 | second_min_val = node.val 11 | 12 | find_second_min_val_helper(node.left) 13 | find_second_min_val_helper(node.right) 14 | 15 | min_val = second_min_val = float('inf') 16 | find_second_min_val_helper(root) 17 | 18 | return second_min_val if second_min_val != float('inf') else -1 -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_783_min_distance_between_bst_nodes/min_distance_between_bst_nodes.py: -------------------------------------------------------------------------------- 1 | def min_diff_in_bst(root): 2 | def min_diff_in_bst_helper(node): 3 | nonlocal min_distance, prev_val 4 | if node is None: return 5 | 6 | min_diff_in_bst_helper(node.left) 7 | 8 | if prev_val != float('inf'): 9 | min_distance = min(min_distance, node.val - prev_val) 10 | prev_val = node.val 11 | 12 | min_diff_in_bst_helper(node.right) 13 | 14 | min_distance = prev_val = float('inf') 15 | min_diff_in_bst_helper(root) 16 | 17 | return min_distance -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_94_inorder_traversal/README.md: -------------------------------------------------------------------------------- 1 | # [LC 94. Binary Tree Inorder Traversal - Easy](https://leetcode.com/problems/binary-tree-inorder-traversal/description/) 2 | 3 | Given the root of a binary tree, return the inorder traversal of its nodes' values. 4 | 5 |
6 | 7 | ### Example 1 8 | 9 | ![InOrder Traversal Example 1](https://assets.leetcode.com/uploads/2020/09/15/inorder_1.jpg) 10 | 11 | 12 | ``` 13 | Input: root = [1,null,2,3] 14 | Output: [1,3,2] 15 | ``` 16 | 17 | ### Example 2 18 | 19 | ``` 20 | Input: root = [] 21 | Output: [] 22 | ``` 23 | 24 | ### Example 3 25 | 26 | ``` 27 | Input: root = [1] 28 | Output: [1] 29 | ``` 30 | 31 | ### Constraints: 32 | 33 | - The number of nodes in the tree is in the range [0, 100]. 34 | - -100 <= Node.val <= 100 -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_95_unique_binary_search_trees_II/README.md: -------------------------------------------------------------------------------- 1 | # [LC 95. Unique Binary Search Trees II - Medium](https://leetcode.com/problems/unique-binary-search-trees-ii/description/) 2 | 3 | Given an integer n, return all the structurally unique BST's (binary search trees), which has exactly n nodes of unique values from 1 to n. Return the answer in any order. 4 | 5 | ### Example 1 6 | 7 | ![Unique Binary Search Trees II Example 1](https://assets.leetcode.com/uploads/2021/01/18/uniquebstn3.jpg) 8 | 9 | 10 | ``` 11 | Input: n = 3 12 | Output: [[1,null,2,null,3],[1,null,3,2],[2,1,3],[3,1,null,null,2],[3,2,null,1]] 13 | ``` 14 | 15 | ### Example 2 16 | 17 | ``` 18 | Input: n = 1 19 | Output: [[1]] 20 | ``` 21 | 22 | 23 | ### Constraints: 24 | 25 | - 1 <= n <= 8 -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_95_unique_binary_search_trees_II/unique_binary_search_trees.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/leetcode/src/binary_trees/lc_95_unique_binary_search_trees_II/unique_binary_search_trees.py -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_96_unique_binary_search_trees/README.md: -------------------------------------------------------------------------------- 1 | # [LC 96. Unique Binary Search Trees - Medium](https://leetcode.com/problems/unique-binary-search-trees/description/) 2 | 3 | Given an integer n, return the number of structurally unique BST's (binary search trees) which has exactly n nodes of unique values from 1 to n. 4 | 5 | ### Example 1 6 | 7 | ![Unique Binary Search Trees Example 1](https://assets.leetcode.com/uploads/2021/01/18/uniquebstn3.jpg) 8 | 9 | 10 | ``` 11 | Input: n = 3 12 | Output: 5 13 | ``` 14 | 15 | ### Example 2 16 | 17 | ``` 18 | Input: n = 1 19 | Output: 1 20 | ``` 21 | 22 | 23 | ### Constraints: 24 | 25 | - 1 <= n <= 19 -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_96_unique_binary_search_trees/unique_binary_search_trees.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/leetcode/src/binary_trees/lc_96_unique_binary_search_trees/unique_binary_search_trees.py -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_98_validate_binary_search_tree/validate_binary_search_tree.py: -------------------------------------------------------------------------------- 1 | def valid_bst(root): 2 | def valid_bst_helper(node, lower_bound, upper_bound): 3 | if node is None: return True 4 | 5 | if not (lower_bound < node.val < upper_bound): 6 | return False 7 | 8 | return (valid_bst_helper(node.left, lower_bound, node.val) and 9 | valid_bst_helper(node.right, node.val, upper_bound)) 10 | 11 | return valid_bst_helper(root, float('-inf'), float('inf')) -------------------------------------------------------------------------------- /leetcode/src/binary_trees/lc_99_recover_binary_search_trees/recover_binary_search_trees.py: -------------------------------------------------------------------------------- 1 | def recover_bst(root): 2 | def recover_bst_helper(node): 3 | nonlocal prev, first, middle, last 4 | if not node: return 5 | 6 | recover_bst_helper(node.left) 7 | if prev and prev.val > node.val: 8 | if not first: 9 | first, middle = prev, node 10 | else: 11 | last = node 12 | 13 | prev = node 14 | recover_bst_helper(node.right) 15 | 16 | prev = first = middle = last = None 17 | recover_bst_helper(root) 18 | 19 | if first and last: 20 | first.val, last.val = last.val, first.val 21 | elif first and middle: 22 | first.val, middle.val = middle.val, first.val -------------------------------------------------------------------------------- /leetcode/src/binary_trees/top_view_of_binary_tree/README.md: -------------------------------------------------------------------------------- 1 | # [Top View of Binary Tree - Medium](https://practice.geeksforgeeks.org/problems/top-view-of-binary-tree/1) 2 | 3 | Given a binary tree. The task is to print the top view of binary tree. 4 | Top view of a binary tree is the set of nodes visible when the tree is viewed from the top. 5 | 6 |
7 | 8 | 9 | ### Example 1 10 | 11 | ``` 12 | Input: 13 | 14 | 20 15 | / \ 16 | 8 22 17 | / \ \ 18 | 5 3 25 19 | / \ 20 | 10 14 21 | 22 | Output: 23 | For the above tree, the bottom view is [5, 8, 20, 22, 25] 24 | ``` 25 | 26 | 27 | ### Constraints: 28 | 29 | - 1 <= Number of nodes <= 10^5 30 | - 1 <= Data of a node <= 10^5 -------------------------------------------------------------------------------- /leetcode/src/dp/frog_jump/README.md: -------------------------------------------------------------------------------- 1 | # [FROG JUMP](https://www.codingninjas.com/studio/problems/frog-jump_3621012) 2 | -------------------------------------------------------------------------------- /leetcode/src/dp/lc_152_max_product_subarray/max_product_brute_force.py: -------------------------------------------------------------------------------- 1 | def max_product(nums): 2 | n = len(nums) 3 | if(n == 0): return 0 4 | 5 | result = float('-inf') 6 | for i in range(n): 7 | curr_val = nums[i] 8 | result = max(result, curr_val) 9 | sub_product = 1 10 | for j in range(i+1, n): 11 | sub_product *= nums[j] 12 | result = max(result, sub_product * curr_val) 13 | 14 | return result 15 | 16 | 17 | print(max_product([2,3,-2,4])) # 6 18 | print(max_product([-2,0,-1])) # 0 19 | print(max_product([-2,0,5])) # 5 20 | print(max_product([1,2,-3,0,-4,-5])) # 20 21 | print(max_product([1,2,3,4,5,0])) # 120 22 | print(max_product([2, -1, 0, 3, 1, -1])) # 3 -------------------------------------------------------------------------------- /leetcode/src/dp/lc_152_max_product_subarray/max_product_subarray.py: -------------------------------------------------------------------------------- 1 | def max_product(nums): 2 | result = max(nums) 3 | currMax, currMin = 1, 1 4 | 5 | for num in nums: 6 | if num == 0: 7 | currMax, currMin = 1, 1 8 | continue 9 | tmp = currMax * num 10 | currMax = max(currMax * num, currMin * num, num) 11 | currMin = min(tmp, currMin * num, num) 12 | result = max(result, currMax) 13 | 14 | return result 15 | 16 | 17 | print(max_product([2,3,-2,4])) # 6 18 | print(max_product([-2,0,-1])) # 0 19 | print(max_product([-2,0,5])) # 5 20 | print(max_product([1,2,-3,0,-4,-5])) # 20 21 | print(max_product([1,2,3,4,5,0])) # 120 22 | print(max_product([2, -1, 0, 3, 1, -1])) # 3 -------------------------------------------------------------------------------- /leetcode/src/dp/lc_300_longest_increasing_subsequence/longest_increasing_subsequence.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/leetcode/src/dp/lc_300_longest_increasing_subsequence/longest_increasing_subsequence.py -------------------------------------------------------------------------------- /leetcode/src/dp/lc_472_concatenated_words/concatenated_words.py: -------------------------------------------------------------------------------- 1 | def findAllConcatenatedWordsInADict(words): 2 | result, wordDict = [], set(words) 3 | for word in words: 4 | if wordBreak(word, wordDict): 5 | result.append(word) 6 | 7 | return result 8 | 9 | def wordBreak(s, wordDict): 10 | n = len(s) 11 | dp = [False] * (n + 1) 12 | dp[0] = True 13 | 14 | for i in range(1, n + 1): 15 | for j in range(i): 16 | curr_word = s[j:i] 17 | if dp[j] and curr_word in wordDict and curr_word != s: 18 | dp[i] = True 19 | break 20 | 21 | return dp[n] -------------------------------------------------------------------------------- /leetcode/src/dp/lc_509_fibonacci_number/fibonacci_bottom_up.py: -------------------------------------------------------------------------------- 1 | # Time - O(n) 2 | # Space - O(n) 3 | def fib(n): 4 | dp = [-1] * (n+1) 5 | dp[0] = 0 6 | if n > 0: dp[1] = 1 7 | 8 | for i in range(2, n+1): 9 | dp[i] = dp[i-1] + dp[i-2] 10 | 11 | return dp[n] 12 | 13 | 14 | # Time - O(n) 15 | # Space - O(1) 16 | def fib_optimized(n): 17 | if (n == 0): return 0 18 | prev_2, prev= 0, 1 19 | 20 | for _ in range(2, n+1): 21 | curr = prev_2 + prev 22 | prev_2, prev = prev, curr 23 | 24 | return prev 25 | 26 | print(fib(7)) #13 27 | print(fib(6)) #8 28 | print(fib(5)) #5 29 | print(fib(4)) #3 30 | print(fib(3)) #2 -------------------------------------------------------------------------------- /leetcode/src/dp/lc_509_fibonacci_number/fibonacci_top_down_recursion.py: -------------------------------------------------------------------------------- 1 | # Time - O(n) 2 | # Space - O(n) + O(n) -> recursion stack + memoization space used 3 | def fib(n): 4 | memo = [-1] * (n+1) 5 | fib_top_down(n, memo) 6 | 7 | return memo[n] 8 | 9 | 10 | def fib_top_down(n, memo): 11 | if memo[n] != -1: 12 | return memo[n] 13 | 14 | if n == 0 or n == 1: 15 | memo[n] = n 16 | return memo[n] 17 | 18 | memo[n] = fib_top_down(n-1, memo) + fib_top_down(n-2, memo) 19 | return memo[n] 20 | 21 | 22 | 23 | 24 | print(fib(7)) #13 25 | print(fib(6)) #8 26 | print(fib(5)) #5 27 | print(fib(4)) #3 28 | print(fib(3)) #2 -------------------------------------------------------------------------------- /leetcode/src/dp/lc_70_climbing_stairs/README.md: -------------------------------------------------------------------------------- 1 | # [LC 70. Climbing Stairs - Easy](https://leetcode.com/problems/climbing-stairs/description/) 2 | 3 | You are climbing a staircase. It takes n steps to reach the top. 4 | 5 | Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? 6 | 7 | 8 | ### Example 1 9 | ``` 10 | Input: n = 2 11 | Output: 2 12 | Explanation: There are two ways to climb to the top. 13 | 1. 1 step + 1 step 14 | 2. 2 steps 15 | ``` 16 | 17 | ### Example 2 18 | ``` 19 | Input: n = 3 20 | Output: 3 21 | Explanation: There are three ways to climb to the top. 22 | 1. 1 step + 1 step + 1 step 23 | 2. 1 step + 2 steps 24 | 3. 2 steps + 1 step 25 | ``` 26 | 27 | 28 | ### Constraints: 29 | 30 | - 1 <= n <= 45 -------------------------------------------------------------------------------- /leetcode/src/dp/lc_70_climbing_stairs/climbing_stairs_bottom_up.py: -------------------------------------------------------------------------------- 1 | # Time O(N) 2 | # Space O(N) 3 | def climb(n): 4 | if n <= 2: return n 5 | dp = [-1] * (n+1) 6 | dp[n-1], dp[n-2] = 1, 2 7 | 8 | for i in range(n-3, -1, -1): 9 | dp[i] = dp[i+1] + dp[i+2] 10 | 11 | return dp[0] 12 | 13 | 14 | print(climb(1)) #1 15 | print(climb(2)) #2 16 | print(climb(3)) #3 17 | print(climb(4)) #5 18 | print(climb(5)) #8 19 | -------------------------------------------------------------------------------- /leetcode/src/dp/lc_70_climbing_stairs/climbing_stairs_top_down.py: -------------------------------------------------------------------------------- 1 | # Time O(N) 2 | # Space O(N) + O(N) -> recursion stack + memoization space used 3 | def climb(n): 4 | 5 | def solve(val): 6 | if val > n: return 0 7 | if dp[val] != -1: return dp[val] 8 | if val == n: return 1 9 | 10 | dp[val] = solve(val + 1) + solve(val + 2) 11 | return dp[val] 12 | 13 | dp = [-1] * (n+1) 14 | return solve(0) 15 | 16 | 17 | print(climb(1)) #1 18 | print(climb(2)) #2 19 | print(climb(3)) #3 20 | print(climb(4)) #5 21 | print(climb(5)) #8 22 | -------------------------------------------------------------------------------- /leetcode/src/dp/ninja_training/ninja_training_bottom_up.py: -------------------------------------------------------------------------------- 1 | def ninja_training(training): 2 | pass 3 | 4 | 5 | 6 | print(ninja_training([ 7 | [1, 50, 4], 8 | [3, 100, 11] 9 | ])) #104 10 | 11 | print(ninja_training([ 12 | [1, 2, 5], 13 | [3, 1, 1], 14 | [3, 3, 3], 15 | ])) #11 16 | 17 | print(ninja_training([ 18 | [10, 40, 70], 19 | [20, 50, 80], 20 | [30, 60, 90], 21 | ])) #210 -------------------------------------------------------------------------------- /leetcode/src/graph/README.md: -------------------------------------------------------------------------------- 1 | ## Leetcode Binary Tree Questions 2 | 3 | `E` - Easy, `M` - Medium , `H` - Hard, 4 | 5 | * `M` [Evaluate Division](lc_399_evaluate_division/evaluate_division.py) -------------------------------------------------------------------------------- /leetcode/src/graph/lc_133_clone_graph/clone_graph.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/leetcode/src/graph/lc_133_clone_graph/clone_graph.py -------------------------------------------------------------------------------- /leetcode/src/graph/lc_207_course_schedule_I/course_schedule_I.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/leetcode/src/graph/lc_207_course_schedule_I/course_schedule_I.py -------------------------------------------------------------------------------- /leetcode/src/graph/lc_210_course_schedule_II/course_schedule_II.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/leetcode/src/graph/lc_210_course_schedule_II/course_schedule_II.py -------------------------------------------------------------------------------- /leetcode/src/graph/shortest_path_in_weighted_undirected_graph/README.md: -------------------------------------------------------------------------------- 1 | # [Shortest Path in Weighted undirected graph](https://practice.geeksforgeeks.org/problems/shortest-path-in-weighted-undirected-graph/1) 2 | 3 | 4 | You are given a weighted undirected graph having n vertices numbered from 0 to n-1 and m edges describing there are edges between a to b with some weight. 5 | find the shortest path between the vertex 0 and the vertex n-1 and if path does not exist then return a list consisting of only -1. 6 | 7 | ### Example 1 8 | 9 | ``` 10 | Input: 11 | n = 5, 12 | m= 6, 13 | edge=[[1,2,2], [2,5,5], [2,3,4], [1,4,1],[4,3,3],[3,5,1]] 14 | 15 | Output: [1 4 3 5] 16 | 17 | Explanation: Shortest path from 0 to n-1 is by the path [1 4 3 5] 18 | ``` 19 | 20 | 21 | -------------------------------------------------------------------------------- /leetcode/src/graph/topological_sorting/dfs.py: -------------------------------------------------------------------------------- 1 | def top_sort(v, graph): 2 | visited, ordering = set(), [] 3 | for i in range(v): 4 | if i not in visited: 5 | dfs(i, graph, visited, ordering) 6 | 7 | ordering.reverse() # res = ordering[::-1] (we could also slice and return the result) 8 | return ordering 9 | 10 | def dfs(node, graph, visited, ordering): 11 | visited.add(node) 12 | 13 | for neighbor in graph[node]: 14 | if neighbor not in visited: 15 | dfs(neighbor, graph, visited, ordering) 16 | ordering.append(node) 17 | 18 | graph = [[], [], [3], [1], [0,1], [0,2]] 19 | print(top_sort(6, graph)) -------------------------------------------------------------------------------- /leetcode/src/linkedlist/lc_138_copy_list_with_random_pointer/lc_138_copy_list_with_random_pointer.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None): 3 | self.val = int(x) 4 | self.next = next 5 | self.random = random 6 | 7 | def copyRandomList(head): 8 | clone = {None: None} 9 | node = head 10 | while node: 11 | clone[node] = Node(node.val) 12 | node = node.next 13 | 14 | node = head 15 | while node: 16 | copy = clone[node] 17 | copy.next, copy.random = clone[node.next], clone[node.random] 18 | node = node.next 19 | 20 | return clone[head] -------------------------------------------------------------------------------- /leetcode/src/linkedlist/lc_141_linkedlist_cycle/linkedlist_cycle.py: -------------------------------------------------------------------------------- 1 | def has_cycle(head): 2 | if not head: return False 3 | 4 | slow = fast = head 5 | while fast.next and fast.next.next: 6 | slow, fast = slow.next, fast.next.next 7 | if slow == fast: 8 | return True 9 | 10 | return False -------------------------------------------------------------------------------- /leetcode/src/linkedlist/lc_142_linkedlist_cycle_II/linkedlist_cycle.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | class ListNode: 3 | def __init__(self, x): 4 | self.val = x 5 | self.next = None 6 | 7 | 8 | def detectCycle(head): 9 | slow = fast = head 10 | 11 | while fast and fast.next: 12 | slow, fast = slow.next, fast.next.next 13 | if slow == fast: 14 | pointer = head 15 | while pointer and slow and pointer != slow: 16 | slow, pointer = slow.next, pointer.next 17 | 18 | return pointer -------------------------------------------------------------------------------- /leetcode/src/linkedlist/lc_147_insertion_sort/insertion_sort.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | class ListNode: 3 | def __init__(self, val=0, next=None): 4 | self.val = val 5 | self.next = next 6 | 7 | 8 | 9 | def insertionSortList(head): 10 | sentinel, curr = ListNode(), head 11 | 12 | while curr: 13 | prev = sentinel 14 | while prev.next and curr.val >= prev.next.val: 15 | prev = prev.next 16 | 17 | next_node = curr.next 18 | curr.next = prev.next 19 | prev.next = curr 20 | 21 | curr = next_node 22 | 23 | return sentinel.next -------------------------------------------------------------------------------- /leetcode/src/linkedlist/lc_160_intersection_of_two_linkedlists/intersection_of_two_linkedlists.py: -------------------------------------------------------------------------------- 1 | def getIntersectionNode(headA, headB): 2 | if not headA or not headB: return 3 | A_count, B_count = count_list(headA), count_list(headB) 4 | 5 | if B_count > A_count: 6 | headA, headB = headB, headA 7 | 8 | i = 0 9 | while i < abs(A_count - B_count): 10 | headA = headA.next 11 | i += 1 12 | 13 | while headA and headB and headA != headB: 14 | headA, headB = headA.next, headB.next 15 | 16 | return headA 17 | 18 | 19 | def count_list(node): 20 | count = 0 21 | while node: 22 | node = node.next 23 | count += 1 24 | 25 | return count -------------------------------------------------------------------------------- /leetcode/src/linkedlist/lc_19_remove_nth_node_from_list/remove_nth_node_from_list.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | class ListNode: 3 | def __init__(self, val=0, next=None): 4 | self.val = val 5 | self.next = next 6 | 7 | def removeNthFromEnd(head, n): 8 | sentinel = slow = ListNode(-1, head) 9 | fast = head 10 | 11 | while fast and n > 0: 12 | fast = fast.next 13 | n -= 1 14 | 15 | while fast: 16 | slow, fast = slow.next, fast.next 17 | 18 | slow.next = slow.next.next 19 | return sentinel.next -------------------------------------------------------------------------------- /leetcode/src/linkedlist/lc_206_reverse_linkedlist/reverse_linkedlist.py: -------------------------------------------------------------------------------- 1 | def reverse_list(head): 2 | prev, curr = None, head 3 | while curr: 4 | next_node = curr.next 5 | curr.next = prev 6 | prev, curr = curr, next_node 7 | 8 | return prev -------------------------------------------------------------------------------- /leetcode/src/linkedlist/lc_21_merge_two_sorted_lists/merge_two_sorted_lists.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | class ListNode: 3 | def __init__(self, val=0, next=None): 4 | self.val = val 5 | self.next = next 6 | 7 | # Time complexity: O(m + n) 8 | # where m and n represents the length of the two list nodes 9 | # Space complexity: O(1) 10 | def mergeTwoLists(list1, list2): 11 | sentinel = merge = ListNode(0) 12 | while list1 and list2: 13 | if list1.val < list2.val: 14 | merge.next, list1 = list1, list1.next 15 | else: 16 | merge.next, list2 = list2, list2.next 17 | merge = merge.next 18 | 19 | merge.next = list1 or list2 20 | return sentinel.next -------------------------------------------------------------------------------- /leetcode/src/linkedlist/lc_24_swap_nodes_in_pairs/swap_nodes_in_pairs.py: -------------------------------------------------------------------------------- 1 | def swapPairs(head): 2 | if not head or not head.next: return head 3 | 4 | prev, curr = None, head 5 | while curr: 6 | last_node_previous_sublist, last_node_of_sublist = prev, curr 7 | i = 2 8 | while curr and i > 0: 9 | next_node = curr.next 10 | curr.next = prev 11 | prev, curr = curr, next_node 12 | i -= 1 13 | 14 | if last_node_previous_sublist is None: 15 | head = prev 16 | else: 17 | last_node_previous_sublist.next = prev 18 | 19 | last_node_of_sublist.next = curr 20 | prev = last_node_of_sublist 21 | return head -------------------------------------------------------------------------------- /leetcode/src/linkedlist/lc_2_add_two_numbers/add_two_numbers.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | class ListNode: 3 | def __init__(self, val=0, next=None): 4 | self.val = val 5 | self.next = next 6 | 7 | 8 | def addTwoNumbers(l1, l2): 9 | result_iter = result = ListNode(0) 10 | remainder = 0 11 | while l1 or l2 or remainder: 12 | l1_val = l1.val if l1 else 0 13 | l2_val = l2.val if l2 else 0 14 | 15 | curr_sum = l1_val + l2_val + remainder 16 | result_iter.next = ListNode(curr_sum % 10) 17 | remainder = curr_sum // 10 18 | 19 | l1 = l1.next if l1 else None 20 | l2 = l2.next if l2 else None 21 | result_iter = result_iter.next 22 | 23 | return result.next -------------------------------------------------------------------------------- /leetcode/src/linkedlist/lc_328_odd_even_linkedlist/odd_even_linkedlist.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | class ListNode: 3 | def __init__(self, val=0, next=None): 4 | self.val = val 5 | self.next = next 6 | 7 | 8 | # Time O(n) | Space O(1) 9 | def oddEvenList(head): 10 | if not head: return head 11 | even_head = even_it = ListNode() 12 | odd_head = odd_it = ListNode() 13 | node, i = head, 1 14 | while node: 15 | if i % 2 == 0: 16 | even_it.next = node 17 | even_it = even_it.next 18 | else: 19 | odd_it.next = node 20 | odd_it = odd_it.next 21 | i += 1 22 | node = node.next 23 | 24 | even_it.next, odd_it.next = None, even_head.next 25 | return odd_head.next -------------------------------------------------------------------------------- /leetcode/src/linkedlist/lc_61_rotate_list/README.md: -------------------------------------------------------------------------------- 1 | # [LC 61. Rotate List - Medium](https://leetcode.com/problems/rotate-list/description/) 2 | 3 | Given the head of a linked list, rotate the list to the right by k places. 4 | 5 | ### Example 1 6 | 7 | ![ Rotate List Example 1](https://assets.leetcode.com/uploads/2020/11/13/rotate1.jpg) 8 | 9 | ``` 10 | Input: head = [1,2,3,4,5], k = 2 11 | Output: [4,5,1,2,3] 12 | ``` 13 | 14 | ### Example 2 15 | 16 | ![ Rotate List Example 2](https://assets.leetcode.com/uploads/2020/11/13/roate2.jpg) 17 | 18 | ``` 19 | Input: head = [0,1,2], k = 4 20 | Output: [2,0,1] 21 | ``` 22 | 23 | 24 | ### Constraints: 25 | 26 | - The number of nodes in the list is in the range [0, 500]. 27 | - -100 <= Node.val <= 100 28 | - 0 <= k <= 2 * 10^9 -------------------------------------------------------------------------------- /leetcode/src/linkedlist/lc_82_remove_duplicates_from_sorted_list_II/remove_duplicates_from_sorted_list_II.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list. 2 | class ListNode: 3 | def __init__(self, val=0, next=None): 4 | self.val = val 5 | self.next = next 6 | 7 | 8 | def deleteDuplicates(head): 9 | sentinel = result = ListNode(0) 10 | node = head 11 | while node: 12 | it, is_duplicate = node.next, False 13 | while it and it.val == node.val: 14 | is_duplicate = True 15 | it = it.next 16 | 17 | if not is_duplicate: 18 | result.next = node 19 | result = result.next 20 | node = it 21 | 22 | result.next = None 23 | return sentinel.next -------------------------------------------------------------------------------- /leetcode/src/recursion/lc_60_permutation_sequence/permutation_sequence.py: -------------------------------------------------------------------------------- 1 | def getPermutation(n, k): 2 | factorial = 1 3 | nums = [] 4 | for i in range(1, n): 5 | factorial *= i 6 | nums.append(i) 7 | 8 | nums.append(n) 9 | result, k = [], k-1 10 | 11 | while True: 12 | next_val = nums[k//factorial] 13 | result.append(str(next_val)) 14 | nums.remove(next_val) 15 | if(len(nums) == 0): break 16 | k = k % factorial 17 | factorial = factorial // len(nums) 18 | 19 | return "".join(result) 20 | 21 | print(getPermutation(n = 3, k = 3)) 22 | print(getPermutation(n = 4, k = 17)) 23 | print(getPermutation(n = 4, k = 9)) 24 | print(getPermutation(n = 3, k = 1)) -------------------------------------------------------------------------------- /leetcode/src/recursion/lc_726_number_of_atoms/number_of_atoms.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /leetcode/src/recursion/lc_763_partition_labels/partition_labels.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/leetcode/src/recursion/lc_763_partition_labels/partition_labels.py -------------------------------------------------------------------------------- /leetcode/src/recursion/lc_791_custom_sort_string/custom_sort_string.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/leetcode/src/recursion/lc_791_custom_sort_string/custom_sort_string.py -------------------------------------------------------------------------------- /leetcode/src/recursion/lc_795_number_of_subarrays_with_bounded_maximum/number_of_subarrays.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/leetcode/src/recursion/lc_795_number_of_subarrays_with_bounded_maximum/number_of_subarrays.py -------------------------------------------------------------------------------- /leetcode/src/recursion/lc_799_champagne_tower/champagne_tower.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/leetcode/src/recursion/lc_799_champagne_tower/champagne_tower.py -------------------------------------------------------------------------------- /leetcode/src/recursion/lc_810_chalkboard_xor_game/chalkboard_xor_game.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/leetcode/src/recursion/lc_810_chalkboard_xor_game/chalkboard_xor_game.py -------------------------------------------------------------------------------- /leetcode/src/recursion/lc_930_binary_subarrays_with_sum/binary_subarrays_with_sum.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/leetcode/src/recursion/lc_930_binary_subarrays_with_sum/binary_subarrays_with_sum.py -------------------------------------------------------------------------------- /leetcode/src/recursion/lc_975_odd_even_jump/odd_even_jump.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/leetcode/src/recursion/lc_975_odd_even_jump/odd_even_jump.py -------------------------------------------------------------------------------- /leetcode/src/recursion/subset_sum/subset_sum.py: -------------------------------------------------------------------------------- 1 | def subset_sum(nums): 2 | result = [] 3 | subset_sum_helper(nums, result, 0, 0) 4 | result.sort() 5 | return result 6 | 7 | def subset_sum_helper(nums, result, idx, curr_sum): 8 | if idx >= len(nums): 9 | result.append(curr_sum) 10 | return 11 | 12 | subset_sum_helper(nums, result, idx + 1, curr_sum + nums[idx]) 13 | subset_sum_helper(nums, result, idx + 1, curr_sum) 14 | 15 | 16 | 17 | 18 | print(subset_sum([3,1,2])) 19 | print(subset_sum([4,2,2,6])) -------------------------------------------------------------------------------- /leetcode/src/trie/lc_211_design_add_and_search_words_data_structure/design_add_and_search_words_data_structure.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/leetcode/src/trie/lc_211_design_add_and_search_words_data_structure/design_add_and_search_words_data_structure.py -------------------------------------------------------------------------------- /leetcode/src/trie/lc_212_word_search_II/word_search_II.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/leetcode/src/trie/lc_212_word_search_II/word_search_II.py -------------------------------------------------------------------------------- /leetcode/src/trie/lc_421_max_xor_of_two_numbers_in_array/README.md: -------------------------------------------------------------------------------- 1 | # [LC 421. Maximum XOR of Two Numbers in an Array - Medium](https://leetcode.com/problems/maximum-xor-of-two-numbers-in-an-array/description/) 2 | 3 | Given an integer array nums, return the maximum result of nums[i] XOR nums[j], where 0 <= i <= j < n. 4 | 5 | 6 | ### Example 1 7 | 8 | ``` 9 | Input: nums = [3,10,5,25,2,8] 10 | Output: 28 11 | Explanation: The maximum result is 5 XOR 25 = 28. 12 | ``` 13 | 14 | 15 | ### Example 2 16 | 17 | ``` 18 | Input: nums = [14,70,53,83,49,91,36,80,92,51,66,70] 19 | Output: 127 20 | ``` 21 | 22 | ### Constraints 23 | - 1 <= word.length, prefix.length <= 2000 24 | - word and prefix consist only of lowercase English letters. 25 | - At most 3 * 10^4 calls in total will be made to insert, search, and startsWith -------------------------------------------------------------------------------- /leetcode/src/trie/lc_421_max_xor_of_two_numbers_in_array/max_xor_of_two_numbers_in_array.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/leetcode/src/trie/lc_421_max_xor_of_two_numbers_in_array/max_xor_of_two_numbers_in_array.py -------------------------------------------------------------------------------- /leetcode/src/trie/lc_720_longest_word_in_dictionary/longest_word_in_dictionary_2.py: -------------------------------------------------------------------------------- 1 | def longestWord(words): 2 | words.sort() 3 | longest_word, built_words = "", set() 4 | for word in words: 5 | if len(word) == 1 or word[:len(word) - 1] in built_words: 6 | if len(word) > len(longest_word): 7 | longest_word = word 8 | built_words.add(word) 9 | 10 | return longest_word -------------------------------------------------------------------------------- /patterns/assets/all_paths_for_sum_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/all_paths_for_sum_1.png -------------------------------------------------------------------------------- /patterns/assets/all_paths_for_sum_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/all_paths_for_sum_2.png -------------------------------------------------------------------------------- /patterns/assets/bt_level_order_traversal_eg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/bt_level_order_traversal_eg1.png -------------------------------------------------------------------------------- /patterns/assets/bt_level_order_traversal_eg2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/bt_level_order_traversal_eg2.png -------------------------------------------------------------------------------- /patterns/assets/bt_reverse_level_order_traversal_eg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/bt_reverse_level_order_traversal_eg1.png -------------------------------------------------------------------------------- /patterns/assets/bt_reverse_level_order_traversal_eg2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/bt_reverse_level_order_traversal_eg2.png -------------------------------------------------------------------------------- /patterns/assets/btree_path_sum_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/btree_path_sum_1.png -------------------------------------------------------------------------------- /patterns/assets/btree_path_sum_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/btree_path_sum_2.png -------------------------------------------------------------------------------- /patterns/assets/connect_all_level_order_siblings_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/connect_all_level_order_siblings_1.png -------------------------------------------------------------------------------- /patterns/assets/connect_all_level_order_siblings_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/connect_all_level_order_siblings_2.png -------------------------------------------------------------------------------- /patterns/assets/count_paths_sum_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/count_paths_sum_1.png -------------------------------------------------------------------------------- /patterns/assets/count_paths_sum_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/count_paths_sum_2.png -------------------------------------------------------------------------------- /patterns/assets/find_leaves.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/find_leaves.png -------------------------------------------------------------------------------- /patterns/assets/happy_number_eg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/happy_number_eg1.png -------------------------------------------------------------------------------- /patterns/assets/happy_number_eg2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/happy_number_eg2.png -------------------------------------------------------------------------------- /patterns/assets/level_averages_eg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/level_averages_eg1.png -------------------------------------------------------------------------------- /patterns/assets/level_averages_eg2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/level_averages_eg2.png -------------------------------------------------------------------------------- /patterns/assets/level_order_siblings_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/level_order_siblings_1.png -------------------------------------------------------------------------------- /patterns/assets/level_order_siblings_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/level_order_siblings_2.png -------------------------------------------------------------------------------- /patterns/assets/level_order_successor_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/level_order_successor_1.png -------------------------------------------------------------------------------- /patterns/assets/level_order_successor_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/level_order_successor_2.png -------------------------------------------------------------------------------- /patterns/assets/level_order_successor_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/level_order_successor_3.png -------------------------------------------------------------------------------- /patterns/assets/linkedlist_cycle_start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/linkedlist_cycle_start.png -------------------------------------------------------------------------------- /patterns/assets/median_of_stream.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/median_of_stream.png -------------------------------------------------------------------------------- /patterns/assets/merge_intervals.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/merge_intervals.png -------------------------------------------------------------------------------- /patterns/assets/min_depth_of_binary_tree_eg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/min_depth_of_binary_tree_eg1.png -------------------------------------------------------------------------------- /patterns/assets/min_depth_of_binary_tree_eg2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/min_depth_of_binary_tree_eg2.png -------------------------------------------------------------------------------- /patterns/assets/min_meeting_rooms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/min_meeting_rooms.png -------------------------------------------------------------------------------- /patterns/assets/path_with_max_sum_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/path_with_max_sum_1.png -------------------------------------------------------------------------------- /patterns/assets/path_with_max_sum_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/path_with_max_sum_2.png -------------------------------------------------------------------------------- /patterns/assets/path_with_sequence_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/path_with_sequence_1.png -------------------------------------------------------------------------------- /patterns/assets/path_with_sequence_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/path_with_sequence_2.png -------------------------------------------------------------------------------- /patterns/assets/reverse_alternating_k-element_sublist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/reverse_alternating_k-element_sublist.png -------------------------------------------------------------------------------- /patterns/assets/reverse_k_sublist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/reverse_k_sublist.png -------------------------------------------------------------------------------- /patterns/assets/reverse_linkedlist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/reverse_linkedlist.png -------------------------------------------------------------------------------- /patterns/assets/reverse_sublist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/reverse_sublist.png -------------------------------------------------------------------------------- /patterns/assets/right_view_of_binary_tree_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/right_view_of_binary_tree_1.png -------------------------------------------------------------------------------- /patterns/assets/right_view_of_binary_tree_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/right_view_of_binary_tree_2.png -------------------------------------------------------------------------------- /patterns/assets/rotate_linkedlist_eg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/rotate_linkedlist_eg1.png -------------------------------------------------------------------------------- /patterns/assets/rotate_linkedlist_eg2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/rotate_linkedlist_eg2.png -------------------------------------------------------------------------------- /patterns/assets/rotation_count_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/rotation_count_1.png -------------------------------------------------------------------------------- /patterns/assets/rotation_count_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/rotation_count_2.png -------------------------------------------------------------------------------- /patterns/assets/search_rotated_array_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/search_rotated_array_1.png -------------------------------------------------------------------------------- /patterns/assets/search_rotated_array_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/search_rotated_array_2.png -------------------------------------------------------------------------------- /patterns/assets/search_rotated_array_with_dups.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/search_rotated_array_with_dups.png -------------------------------------------------------------------------------- /patterns/assets/sum_of_path_numbers_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/sum_of_path_numbers_1.png -------------------------------------------------------------------------------- /patterns/assets/sum_of_path_numbers_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/sum_of_path_numbers_2.png -------------------------------------------------------------------------------- /patterns/assets/topological_sort_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/topological_sort_1.png -------------------------------------------------------------------------------- /patterns/assets/topological_sort_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/topological_sort_2.png -------------------------------------------------------------------------------- /patterns/assets/topological_sort_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/topological_sort_3.png -------------------------------------------------------------------------------- /patterns/assets/tree_diameter_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/tree_diameter_1.png -------------------------------------------------------------------------------- /patterns/assets/tree_diameter_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/tree_diameter_2.png -------------------------------------------------------------------------------- /patterns/assets/zigzag_traversal_eg1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/zigzag_traversal_eg1.png -------------------------------------------------------------------------------- /patterns/assets/zigzag_traversal_eg2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/assets/zigzag_traversal_eg2.png -------------------------------------------------------------------------------- /patterns/src/10_subsets/README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | A huge number of coding interview problems involve dealing with Permutations and Combinations 4 | of a given set of elements. 5 | This pattern describes an efficient Breadth First Search (BFS) approach to handle all these problems. -------------------------------------------------------------------------------- /patterns/src/10_subsets/balanced_parenthesis/README.md: -------------------------------------------------------------------------------- 1 | # Balanced Parentheses (hard) ✩ 2 | 3 | For a given number ‘N’, write a function to generate all combination of ‘N’ pairs of balanced parentheses. 4 | 5 | ### Example 1 6 | Input: N=2 7 | Output: (()), ()() 8 | 9 | ### Example 1 10 | Input: N=3 11 | Output: ((())), (()()), (())(), ()(()), ()()() -------------------------------------------------------------------------------- /patterns/src/10_subsets/permutations/README.md: -------------------------------------------------------------------------------- 1 | # Permutations (medium) ✩ 2 | 3 | Given a set of distinct numbers, find all of its permutations. 4 | 5 | Permutation is defined as the re-arranging of the elements of the set. For example, {1, 2, 3} has the following six permutations: 6 | 7 | 1. {1, 2, 3} 8 | 2. {1, 3, 2} 9 | 3. {2, 1, 3} 10 | 4. {2, 3, 1} 11 | 5. {3, 1, 2} 12 | 6. {3, 2, 1} 13 | 14 | If a set has ‘n’ distinct elements it will have n!n! permutations. 15 | 16 | ### Example 1 17 | Input: [1,3,5] 18 | Output: [1,3,5], [1,5,3], [3,1,5], [3,5,1], [5,1,3], [5,3,1] 19 | 20 | -------------------------------------------------------------------------------- /patterns/src/10_subsets/string_permutations_by_changing_case/README.md: -------------------------------------------------------------------------------- 1 | # String Permutations by changing case (medium) ✩ 2 | 3 | Given a string, find all of its permutations preserving the character sequence but changing case. 4 | 5 | ### Example 1 6 | Input: "ad52" 7 | Output: "ad52", "Ad52", "aD52", "AD52" 8 | 9 | ### Example 1 10 | Input: "ab7c" 11 | Output: "ab7c", "Ab7c", "aB7c", "AB7c", "ab7C", "Ab7C", "aB7C", "AB7C" -------------------------------------------------------------------------------- /patterns/src/10_subsets/subsets/README.md: -------------------------------------------------------------------------------- 1 | # Subsets (easy) ✩ 2 | 3 | Given a set with distinct elements, find all of its distinct subsets. 4 | 5 | ### Example 1 6 | Input: [1, 3] 7 | Output: [], [1], [3], [1,3] 8 | 9 | ### Example 2 10 | Input: [1, 5, 3] 11 | Output: [], [1], [5], [3], [1,5], [1,3], [5,3], [1,5,3] 12 | -------------------------------------------------------------------------------- /patterns/src/10_subsets/subsets_with_duplicates/README.md: -------------------------------------------------------------------------------- 1 | # Subsets With Duplicates (easy) ✩ 2 | 3 | Given a set with distinct elements, find all of its distinct subsets. 4 | 5 | ### Example 1 6 | Input: [1, 3, 3] 7 | Output: [], [1], [3], [1,3], [3,3], [1,3,3] 8 | 9 | ### Example 2 10 | Input: [1, 5, 3, 3] 11 | Output: [], [1], [5], [3], [1,5], [1,3], [5,3], [1,5,3], [3,3], [1,3,3], [3,3,5], [1,5,3,3] 12 | -------------------------------------------------------------------------------- /patterns/src/10_subsets/unique_generalized_abbreviation/unique_gen_abbrev.py: -------------------------------------------------------------------------------- 1 | from collections import deque 2 | 3 | def generate_generalized_abbreviation(word): 4 | return 5 | 6 | 7 | print("Generalized abbreviation are: " + 8 | str(generate_generalized_abbreviation("BAT"))) 9 | print("Generalized abbreviation are: " + 10 | str(generate_generalized_abbreviation("code"))) -------------------------------------------------------------------------------- /patterns/src/11_modified_binary_search/10_rotation_count/rotation_count.py: -------------------------------------------------------------------------------- 1 | def count_rotations(arr): 2 | start, end = 0, len(arr) - 1 3 | while start < end: 4 | mid = start + (end - start) // 2 5 | 6 | if mid < end and arr[mid] > arr[mid + 1]: 7 | return mid + 1 8 | 9 | if mid > start and arr[mid] < arr[mid - 1]: 10 | return mid 11 | 12 | if arr[start] < arr[mid]: 13 | start = mid + 1 14 | else: 15 | end = mid - 1 16 | 17 | return 0 18 | 19 | print(count_rotations([10, 15, 1, 3, 8])) 20 | print(count_rotations([4, 5, 7, 9, 10, -1, 2])) 21 | print(count_rotations([1, 3, 8, 10])) -------------------------------------------------------------------------------- /patterns/src/11_modified_binary_search/11_search_in_rotated_array_with_duplicates/README.md: -------------------------------------------------------------------------------- 1 | # Search in Rotated Array With Duplicates (medium) ✩ 2 | 3 | Given an array of numbers which is sorted in ascending order and 4 | also rotated by some arbitrary number, find if a given ‘key’ is present in it. 5 | 6 | Write a function to return the index of the ‘key’ in the rotated array. 7 | If the ‘key’ is not present, return -1. You can assume that the given array can have duplicates. 8 | 9 | ### Example 1 10 | ``` 11 | Input: [3, 7, 3, 3, 3], key = 7 12 | Output: 1 13 | Explanation: '7' is present in the array at index '1'. 14 | ``` 15 | 16 | ![Search in Rotated Array Example 1](./../../../assets/search_rotated_array_with_dups.png) 17 | 18 | -------------------------------------------------------------------------------- /patterns/src/11_modified_binary_search/4_number_range/README.md: -------------------------------------------------------------------------------- 1 | # Number Range (medium) ✩ 2 | 3 | Given an array of numbers sorted in ascending order, find the range of a given number ‘key’. 4 | The range of the ‘key’ will be the first and last position of the ‘key’ in the array. 5 | 6 | Write a function to return the range of the ‘key’. If the ‘key’ is not present return [-1, -1]. 7 | 8 | ### Example 1 9 | ``` 10 | Input: [4, 6, 6, 6, 9], key = 6 11 | Output: [1, 3] 12 | ``` 13 | 14 | ### Example 2 15 | ``` 16 | Input: [1, 3, 8, 10, 15], key = 10 17 | Output: [3, 3] 18 | ``` 19 | 20 | ### Example 3 21 | ``` 22 | Input: [1, 3, 8, 10, 15], key = 12 23 | Output: [-1, -1] 24 | ``` 25 | -------------------------------------------------------------------------------- /patterns/src/11_modified_binary_search/6_minimum_difference_element/README.md: -------------------------------------------------------------------------------- 1 | # Minimum Difference Element (medium) ✩ 2 | 3 | Given an array of numbers sorted in ascending order, 4 | find the element in the array that has the minimum difference with the given ‘key’. 5 | 6 | 7 | 8 | ### Example 1 9 | ``` 10 | Input: [4, 6, 10], key = 7 11 | Output: 6 12 | Explanation: The difference between the key '7' and '6' is minimum than any other number in the array 13 | ``` 14 | 15 | ### Example 2 16 | ``` 17 | Input: [4, 6, 10], key = 4 18 | Output: 4 19 | ``` 20 | 21 | ### Example 3 22 | ``` 23 | Input: [1, 3, 8, 10, 15], key = 15 24 | Output: 4 25 | Explanation: The key is present at index '4' in the array. 26 | ``` 27 | 28 | ### Example 4 29 | ``` 30 | Input: [4, 6, 10], key = 17 31 | Output: 10 32 | ``` -------------------------------------------------------------------------------- /patterns/src/11_modified_binary_search/7_bitonic_array_maximum/README.md: -------------------------------------------------------------------------------- 1 | # Bitonic Array Maximum (easy) ✩ 2 | 3 | Find the maximum value in a given Bitonic array. An array is considered bitonic 4 | if it is monotonically increasing and then monotonically decreasing. 5 | Monotonically increasing or decreasing means that for any index i in the array arr[i] != arr[i+1]. 6 | 7 | ### Example 1 8 | ``` 9 | Input: [1, 3, 8, 12, 4, 2] 10 | Output: 12 11 | Explanation: The maximum number in the input bitonic array is '12'. 12 | ``` 13 | 14 | ### Example 2 15 | ``` 16 | Input: [3, 8, 3, 1] 17 | Output: 8 18 | ``` 19 | 20 | ### Example 3 21 | ``` 22 | Input: [1, 3, 8, 12] 23 | Output: 12 24 | ``` 25 | 26 | ### Example 4 27 | ``` 28 | Input: [10, 9, 8] 29 | Output: 10 30 | ``` -------------------------------------------------------------------------------- /patterns/src/12_top_k_elements/README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Any problem that asks us to find the top/smallest/frequent ‘K’ elements among a given set falls under this pattern. 4 | 5 | The best data structure that comes to mind to keep track of ‘K’ elements is Heap. 6 | This pattern will make use of the Heap to solve multiple problems 7 | dealing with ‘K’ elements at a time from a set of given elements. -------------------------------------------------------------------------------- /patterns/src/12_top_k_elements/connect_ropes/README.md: -------------------------------------------------------------------------------- 1 | # Connect Ropes (easy) ✩ 2 | 3 | Given ‘N’ ropes with different lengths, we need to connect these ropes into one 4 | big rope with minimum cost. The cost of connecting two ropes is equal to the sum of their lengths. 5 | 6 | ### Example 1 7 | ``` 8 | Input: [1, 3, 11, 5] 9 | Output: 33 10 | Explanation: First connect 1+3(=4), then 4+5(=9), and then 9+11(=20). So the total cost is 33 (4+9+20) 11 | ``` 12 | 13 | ### Example 2 14 | ``` 15 | Input: [3, 4, 5, 6] 16 | Output: 36 17 | Explanation: First connect 3+4(=7), then 5+6(=11), 7+11(=18). Total cost is 36 (7+11+18) 18 | ``` 19 | 20 | ### Example 3 21 | ``` 22 | Input: [1, 3, 11, 5, 2] 23 | Output: 42 24 | Explanation: First connect 1+2(=3), then 3+3(=6), 6+5(=11), 11+11(=22). Total cost is 42 (3+6+11+22) 25 | ``` -------------------------------------------------------------------------------- /patterns/src/12_top_k_elements/frequency_sort/README.md: -------------------------------------------------------------------------------- 1 | # Frequency Sort (medium) ✩ 2 | 3 | Given a string, sort it based on the decreasing frequency of its characters. 4 | 5 | ### Example 1 6 | ``` 7 | Input: "Programming" 8 | Output: "ggmmrrPaino" 9 | Explanation: 'r', 'g', and 'm' appeared twice, so they need to appear before any other character. 10 | ``` 11 | 12 | ### Example 2 13 | ``` 14 | Input: "abcbab" 15 | Output: "bbbaac" 16 | Explanation: 'b' appeared three times, 'a' appeared twice, and 'c' appeared only once. 17 | ``` 18 | 19 | -------------------------------------------------------------------------------- /patterns/src/12_top_k_elements/k_closest_numbers/README.md: -------------------------------------------------------------------------------- 1 | # 'K' Closest Numbers (medium) ✩ 2 | 3 | Given a sorted number array and two integers ‘K’ and ‘X’, 4 | find ‘K’ closest numbers to ‘X’ in the array. Return the numbers in the sorted order. 5 | ‘X’ is not necessarily present in the array. 6 | 7 | 8 | ### Example 1 9 | ``` 10 | Input: [5, 6, 7, 8, 9], K = 3, X = 7 11 | Output: [6, 7, 8] 12 | ``` 13 | 14 | ### Example 2 15 | ``` 16 | Input: [2, 4, 5, 6, 9], K = 3, X = 6 17 | Output: [4, 5, 6] 18 | ``` 19 | 20 | ### Example 3 21 | ``` 22 | Input: [2, 4, 5, 6, 9], K = 3, X = 10 23 | Output: [5, 6, 9] 24 | ``` -------------------------------------------------------------------------------- /patterns/src/12_top_k_elements/k_closest_point_to_origin/README.md: -------------------------------------------------------------------------------- 1 | # 'K' Closest Points to the Origin (easy) ✩ 2 | 3 | Given an array of points in a 2D plane, find ‘K’ closest points to the origin. 4 | 5 | ### Example 1 6 | ``` 7 | Input: points = [[1,2],[1,3]], K = 1 8 | Output: [[1,2]] 9 | Explanation: The Euclidean distance between (1, 2) and the origin is sqrt(5). 10 | The Euclidean distance between (1, 3) and the origin is sqrt(10). 11 | Since sqrt(5) < sqrt(10), therefore (1, 2) is closer to the origin. 12 | ``` 13 | 14 | ### Example 2 15 | ``` 16 | Input: point = [[1, 3], [3, 4], [2, -1]], K = 2 17 | Output: [[1, 3], [2, -1]] 18 | ``` 19 | 20 | -------------------------------------------------------------------------------- /patterns/src/12_top_k_elements/kth_largest_number_in_stream/README.md: -------------------------------------------------------------------------------- 1 | # Kth Largest Number in a Stream (medium) ✩ 2 | 3 | Design a class to efficiently find the Kth largest element in a stream of numbers. 4 | 5 | The class should have the following two things: 6 | 7 | The constructor of the class should accept an integer array containing initial numbers from the stream and an integer ‘K’. 8 | The class should expose a function add(int num) which will store the given number and return the Kth largest number. 9 | 10 | ### Example 1 11 | ``` 12 | Input: [3, 1, 5, 12, 2, 11], K = 4 13 | 1. Calling add(6) should return '5'. 14 | 2. Calling add(13) should return '6'. 15 | 2. Calling add(4) should still return '6'. 16 | ``` 17 | 18 | -------------------------------------------------------------------------------- /patterns/src/12_top_k_elements/top_k_frequent_numbers/README.md: -------------------------------------------------------------------------------- 1 | # Top 'K' Frequent Numbers (medium) ✩ 2 | 3 | Given an unsorted array of numbers, find the top ‘K’ frequently occurring numbers in it. 4 | 5 | ### Example 1 6 | ``` 7 | Input: [1, 3, 5, 12, 11, 12, 11], K = 2 8 | Output: [12, 11] 9 | Explanation: Both '11' and '12' apeared twice. 10 | ``` 11 | 12 | ### Example 2 13 | ``` 14 | Input: [5, 12, 11, 3, 11], K = 2 15 | Output: [11, 5] or [11, 12] or [11, 3] 16 | Explanation: Only '11' appeared twice, all other numbers appeared once. 17 | ``` 18 | -------------------------------------------------------------------------------- /patterns/src/12_top_k_elements/top_k_numbers/README.md: -------------------------------------------------------------------------------- 1 | # Top 'K' Numbers (easy) ✩ 2 | 3 | Given an unsorted array of numbers, find the ‘K’ largest numbers in it. 4 | 5 | ### Example 1 6 | ``` 7 | Input: [3, 1, 5, 12, 2, 11], K = 3 8 | Output: [5, 12, 11] 9 | ``` 10 | 11 | ### Example 2 12 | ``` 13 | IInput: [5, 12, 11, -1, 12], K = 3 14 | Output: [12, 11, 12] 15 | ``` 16 | -------------------------------------------------------------------------------- /patterns/src/13_k_way_merge/README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | This pattern helps us solve problems that involve a list of sorted arrays. 4 | 5 | Whenever we are given ‘K’ sorted arrays, we can use a Heap to efficiently 6 | perform a sorted traversal of all the elements of all arrays. We can push 7 | the smallest (first) element of each sorted array in a Min Heap to get the overall minimum. 8 | 9 | While inserting elements to the Min Heap we keep track of which array the element came from. 10 | We can, then, remove the top element from the heap to get the smallest element and push the 11 | next element from the same array, to which this smallest element belonged, to the heap. 12 | We can repeat this process to make a sorted traversal of all elements. -------------------------------------------------------------------------------- /patterns/src/13_k_way_merge/k_pairs_with_largest_sum/README.md: -------------------------------------------------------------------------------- 1 | # K Pairs with Largest Sums (Hard) ✩ 2 | 3 | Given two sorted arrays in descending order, 4 | find ‘K’ pairs with the largest sum where each pair consists of numbers from both the arrays. 5 | 6 | ### Example 1 7 | ``` 8 | Input: L1=[9, 8, 2], L2=[6, 3, 1], K=3 9 | Output: [9, 3], [9, 6], [8, 6] 10 | Explanation: These 3 pairs have the largest sum. No other pair has a sum larger than any of these. 11 | ``` 12 | 13 | 14 | ### Example 2 15 | ``` 16 | Input: L1=[5, 2, 1], L2=[2, -1], K=3 17 | Output: [5, 2], [5, -1], [2, 2] 18 | 19 | ``` -------------------------------------------------------------------------------- /patterns/src/13_k_way_merge/k_smallest_number_in_m_sorted_list/README.md: -------------------------------------------------------------------------------- 1 | # Kth Smallest Number in M Sorted Lists (medium) ✩ 2 | 3 | Given ‘M’ sorted arrays, find the K’th smallest number among all the arrays. 4 | 5 | ### Example 1 6 | ``` 7 | Input: L1=[2, 6, 8], L2=[3, 6, 7], L3=[1, 3, 4], K=5 8 | Output: 4 9 | Explanation: The 5th smallest number among all the arrays is 4, this can be verified from 10 | the merged list of all the arrays: [1, 2, 3, 3, 4, 6, 6, 7, 8] 11 | ``` 12 | 13 | 14 | ### Example 2 15 | ``` 16 | Input: L1=[5, 8, 9], L2=[1, 7], K=3 17 | Output: 7 18 | Explanation: The 3rd smallest number among all the arrays is 7. 19 | ``` 20 | -------------------------------------------------------------------------------- /patterns/src/13_k_way_merge/kth_smallest_number_in_sorted_matrix.py/README.md: -------------------------------------------------------------------------------- 1 | # Kth Smallest Number in a Sorted Matrix (Hard) ✩ 2 | 3 | Given an N * N matrix where each row and column is sorted in ascending order, 4 | find the Kth smallest element in the matrix. 5 | 6 | ### Example 1 7 | Input: Matrix=[ 8 | [2, 6, 8], 9 | [3, 7, 10], 10 | [5, 8, 11] 11 | ], 12 | K=5 13 | Output: 7 14 | Explanation: The 5th smallest number in the matrix is 7. 15 | 16 | -------------------------------------------------------------------------------- /patterns/src/13_k_way_merge/median_in_sorted_arrays/README.md: -------------------------------------------------------------------------------- 1 | # Median Sorted Arrays (medium) ✩ 2 | 3 | Given ‘M’ sorted arrays, find the median number among all arrays. 4 | 5 | ### Example 1 6 | Input: L1=[3, 5, 7], L2=[0, 6], L3=[0, 6, 28] 7 | Output: 5.5 8 | 9 | ### Example 2 10 | Input: L1=[5, 8, 9], L2=[1, 7] 11 | Output: 7 12 | -------------------------------------------------------------------------------- /patterns/src/13_k_way_merge/merge_k_sorted_arrays/README.md: -------------------------------------------------------------------------------- 1 | # Merge K Sorted Arrays (medium) ✩ 2 | 3 | Given a list of ‘K’ sorted arrays, merge them into one sorted list. 4 | 5 | ### Example 1 6 | Input: L1=[3, 5, 7], L2=[0, 6], L3=[0, 6, 28] 7 | Output: [0, 0, 3, 5, 6, 6, 7, 28] 8 | 9 | ### Example 2 10 | Input: L1=[5, 8, 9], L2=[1, 7] 11 | Output: [1, 5, 7, 8, 9] 12 | -------------------------------------------------------------------------------- /patterns/src/13_k_way_merge/merge_k_sorted_linkedlists/README.md: -------------------------------------------------------------------------------- 1 | # Merge K Sorted LinkedLists (medium) ✩ 2 | 3 | Given an array of ‘K’ sorted LinkedLists, merge them into one sorted list. 4 | 5 | ### Example 1 6 | Input: L1=[2, 6, 8], L2=[3, 6, 7], L3=[1, 3, 4] 7 | Output: [1, 2, 3, 3, 4, 6, 6, 7, 8] 8 | 9 | ### Example 2 10 | Input: L1=[5, 8, 9], L2=[1, 7] 11 | Output: [1, 5, 7, 8, 9] 12 | -------------------------------------------------------------------------------- /patterns/src/13_k_way_merge/smallest_number_range/README.md: -------------------------------------------------------------------------------- 1 | # Smallest Number Range (Hard) ✩ 2 | 3 | Given ‘M’ sorted arrays, find the smallest range that 4 | includes at least one number from each of the ‘M’ lists. 5 | 6 | ### Example 1 7 | ``` 8 | Input: L1=[1, 5, 8], L2=[4, 12], L3=[7, 8, 10] 9 | Output: [4, 7] 10 | Explanation: The range [4, 7] includes 5 from L1, 4 from L2 and 7 from L3. 11 | ``` 12 | 13 | ### Example 2 14 | ``` 15 | Input: L1=[1, 9], L2=[4, 12], L3=[7, 10, 16] 16 | Output: [9, 12] 17 | Explanation: The range [9, 12] includes 9 from L1, 12 from L2 and 10 from L3. 18 | ``` 19 | -------------------------------------------------------------------------------- /patterns/src/14_topological_sort/README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | Topological Sort is used to find a linear ordering of elements that have dependencies on each other. 4 | For example, if event ‘B’ is dependent on event ‘A’, ‘A’ comes before ‘B’ in topological ordering. 5 | 6 | This pattern defines an easy way to understand the technique for performing topological sorting 7 | of a set of elements and then solves a few problems using it. -------------------------------------------------------------------------------- /patterns/src/14_topological_sort/directed_graph_has_cycle/README.md: -------------------------------------------------------------------------------- 1 | # Directed Graph Has Cycle (medium) ✩ 2 | 3 | Find if a given Directed Graph has a cycle in it or not. 4 | 5 | ### Example 1 6 | Input: Vertices=4, Edges=[3, 2], [3, 0], [2, 0], [2, 1], [2, 3] 7 | Output: True 8 | Explanation: 3 is leads 2 and also lead to 3. This creates a cycle 9 | 10 | 11 | ### Example 2 12 | Input: Vertices=5, Edges=[4, 2], [4, 3], [2, 0], [2, 1], [3, 1], [0, 2] 13 | Output: True 14 | 15 | ### Example 3 16 | Input: Vertices=7, Edges=[6, 4], [6, 2], [5, 3], [5, 4], [3, 0], [3, 1], [3, 2], [4, 1] 17 | Output: False 18 | -------------------------------------------------------------------------------- /patterns/src/14_topological_sort/g.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/src/14_topological_sort/g.py -------------------------------------------------------------------------------- /patterns/src/15_dynamic_programming/1_01_knapsack/01_knapsack/01_knapsack_bottom_up_approach.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/src/15_dynamic_programming/1_01_knapsack/01_knapsack/01_knapsack_bottom_up_approach.py -------------------------------------------------------------------------------- /patterns/src/15_dynamic_programming/3_fibonacci_numbers/1_fibonacci_numbers/README.md: -------------------------------------------------------------------------------- 1 | # Fibonacci numbers 2 | 3 | Write a function to calculate the nth Fibonacci number. 4 | 5 | Fibonacci numbers are a series of numbers in which each number is the sum of the two preceding numbers. 6 | 7 | First few Fibonacci numbers are: 0, 1, 1, 2, 3, 5, 8, … 8 | 9 | Mathematically we can define the Fibonacci numbers as: 10 | 11 | Fib(n) = Fib(n-1) + Fib(n-2), for n > 1 12 | 13 | Given that: Fib(0) = 0, and Fib(1) = 1 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /patterns/src/15_dynamic_programming/3_fibonacci_numbers/2_staircase/README.md: -------------------------------------------------------------------------------- 1 | # Staircase 2 | 3 | Given a stair with ‘n’ steps, implement a method to count how many possible ways 4 | are there to reach the top of the staircase, 5 | given that, at every step you can either take 1 step, 2 steps, or 3 steps. 6 | 7 | ### Example 1 8 | Number of stairs (n) : 3 9 | Number of ways = 4 10 | Explanation: Following are the four ways we can climb : {1,1,1}, {1,2}, {2,1}, {3} 11 | 12 | ### Example 2 13 | Number of stairs (n) : 4 14 | Number of ways = 7 15 | Explanation: Following are the seven ways we can climb : {1,1,1,1}, {1,1,2}, {1,2,1}, {2,1,1}, 16 | {2,2}, {1,3}, {3,1} 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /patterns/src/15_dynamic_programming/3_fibonacci_numbers/3_number_factors/README.md: -------------------------------------------------------------------------------- 1 | # Number Factors 2 | 3 | Given a number ‘n’, implement a method to count how many possible ways there are to express ‘n’ as the sum of 1, 3, or 4. 4 | 5 | ### Example 1: 6 | n : 4 7 | Number of ways = 4 8 | Explanation: Following are the four ways we can express 'n' : {1,1,1,1}, {1,3}, {3,1}, {4} 9 | 10 | ### Example 2: 11 | n : 5 12 | Number of ways = 6 13 | Explanation: Following are the six ways we can express 'n' : {1,1,1,1,1}, {1,1,3}, {1,3,1}, {3,1,1}, 14 | {1,4}, {4,1} 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /patterns/src/15_dynamic_programming/3_fibonacci_numbers/3_number_factors/number_factors_bottom_up_approach.py: -------------------------------------------------------------------------------- 1 | # Time Complexity O(n) 2 | # Sapce Complexity O(n) 3 | def count_ways(n): 4 | if n <= 2: 5 | return 1 6 | if n == 3: 7 | return 2 8 | 9 | dp = [0 for _ in range(n+1)] 10 | dp[0], dp[1], dp[2], dp[3] = 1, 1, 1, 2 11 | 12 | for i in range(4, n+1): 13 | dp[i] = dp[i-1] + dp[i-3] + dp[i-4] 14 | 15 | return dp[n] 16 | 17 | 18 | 19 | print("Bottom Up Dynamic Programming") 20 | print(count_ways(4)) 21 | print(count_ways(5)) 22 | print(count_ways(6)) 23 | 24 | -------------------------------------------------------------------------------- /patterns/src/15_dynamic_programming/3_fibonacci_numbers/4_minimum_jumps_to_reach_end/README.md: -------------------------------------------------------------------------------- 1 | # Minimum jumps to reach the end 2 | 3 | Given an array of positive numbers, where each element represents the max number of jumps 4 | that can be made forward from that element, write a program to find the minimum number of 5 | jumps needed to reach the end of the array (starting from the first element). 6 | If an element is 0, then we cannot move through that element. 7 | 8 | ### Example 1: 9 | Input = {2,1,1,1,4} 10 | Output = 3 11 | Explanation: Starting from index '0', we can reach the last index through: 0->2->3->4 12 | 13 | ### Example 2: 14 | Input = {1,1,3,6,9,3,0,1,3} 15 | Output = 4 16 | Explanation: Starting from index '0', we can reach the last index through: 0->1->2->3->8 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /patterns/src/15_dynamic_programming/3_fibonacci_numbers/4_minimum_jumps_to_reach_end/min_jumps_top_down_solution.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/src/15_dynamic_programming/3_fibonacci_numbers/4_minimum_jumps_to_reach_end/min_jumps_top_down_solution.py -------------------------------------------------------------------------------- /patterns/src/15_dynamic_programming/4_palindromic_sequence/count_of_palindromic_substring/README.md: -------------------------------------------------------------------------------- 1 | # Count of Palindromic Substrings 2 | 3 | Given a string, find the total number of palindromic substrings in it. 4 | Please note we need to find the total number of substrings and not subsequences. 5 | 6 | ### Example 1: 7 | ``` 8 | Input: "abdbca" 9 | Output: 7 10 | Explanation: Here are the palindromic substrings, "a", "b", "d", "b", "c", "a", "bdb". 11 | ``` 12 | 13 | ### Example 2: 14 | ``` 15 | Input: = "cddpd" 16 | Output: 7 17 | Explanation: Here are the palindromic substrings, "c", "d", "d", "p", "d", "dd", "dpd". 18 | ``` 19 | 20 | ### Example 3: 21 | ``` 22 | Input: = "pqr" 23 | Output: 3 24 | Explanation: Here are the palindromic substrings,"p", "q", "r". 25 | ``` 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /patterns/src/15_dynamic_programming/4_palindromic_sequence/longest_palindromic_subsequence/README.md: -------------------------------------------------------------------------------- 1 | # Longest Palindromic Subsequence 2 | 3 | Given a sequence, find the length of its Longest Palindromic Subsequence (LPS). 4 | In a palindromic subsequence, elements read the same backward and forward. 5 | 6 | A subsequence is a sequence that can be derived from another sequence by deleting 7 | some or no elements without changing the order of the remaining elements. 8 | 9 | ### Example 1: 10 | Input: "abdbca" 11 | Output: 5 12 | Explanation: LPS is "abdba". 13 | 14 | ### Example 2: 15 | Input: = "cddpd" 16 | Output: 3 17 | Explanation: LPS is "ddd". 18 | 19 | ### Example 3: 20 | Input: = "pqr" 21 | Output: 1 22 | Explanation: LPS could be "p", "q" or "r". 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /patterns/src/15_dynamic_programming/4_palindromic_sequence/longest_palindromic_substring/README.md: -------------------------------------------------------------------------------- 1 | # Longest Palindromic Substring 2 | 3 | Given a string, find the length of its Longest Palindromic Substring (LPS). 4 | In a palindromic string, elements read the same backward and forward. 5 | 6 | 7 | 8 | ### Example 1: 9 | Input: "abdbca" 10 | Output: 3 11 | Explanation: LPS is "bdb". 12 | 13 | ### Example 2: 14 | Input: = "cddpd" 15 | Output: 3 16 | Explanation: LPS is "dpd". 17 | 18 | ### Example 3: 19 | Input: = "pqr" 20 | Output: 1 21 | Explanation: LPS could be "p", "q" or "r". 22 | 23 | -------------------------------------------------------------------------------- /patterns/src/1_sliding_window/average_of_subarrays/README.md: -------------------------------------------------------------------------------- 1 | # Average Of Subarrays (easy) ✩ 2 | 3 | Given an array, find the average of all subarrays of ‘K’ contiguous elements in it. 4 | 5 | 6 | #### Example 1 7 | ``` 8 | Input: [1, 3, 2, 6, -1, 4, 1, 8, 2], K=5 9 | Output: [2.2, 2.8, 2.4, 3.6, 2.8] 10 | 11 | Explanation 12 | 13 | - For the first 5 numbers (subarray from index 0-4), the average is: (1+3+2+6-1)/5 => 2.2 14 | - The average of next 5 numbers (subarray from index 1-5) is: (3+2+6-1+4)/5 => 2.8 15 | - For the next 5 numbers (subarray from index 2-6), the average is: (2+6-1+4+1)/5 => 2.4 16 | - For the next 5 numbers (subarray from index 3-7), the average is: (6-1+4+1+8)/5 => 3.6 17 | - For the next 5 numbers (subarray from index 4-8), the average is: (-1+4+1+8+2)/5 => 2.8 18 | 19 | ``` -------------------------------------------------------------------------------- /patterns/src/1_sliding_window/average_of_subarrays/averages_of_subarrays.py: -------------------------------------------------------------------------------- 1 | def find_averages_of_subarrays(K, arr): 2 | result = [] 3 | window_sum, window_start = 0.0, 0 4 | 5 | for window_end in range(len(arr)): 6 | window_sum += arr[window_end] 7 | 8 | if window_end >= (K - 1): 9 | result.append(window_sum / K) 10 | window_sum -= arr[window_start] 11 | window_start += 1 12 | 13 | return result 14 | 15 | 16 | result = find_averages_of_subarrays(5, [1, 3, 2, 6, -1, 4, 1, 8, 2]) 17 | print("Averages of subarrays of size K: " + str(result)) -------------------------------------------------------------------------------- /patterns/src/1_sliding_window/longest_sub_array_with_ones_after_replacement/README.md: -------------------------------------------------------------------------------- 1 | # Longest Subarray with Ones after Replacement (hard) ✩ 2 | 3 | Given an array containing 0s and 1s, if you are allowed to replace 4 | no more than ‘k’ 0s with 1s, find the length of the longest contiguous subarray having all 1s. 5 | 6 | 7 | #### Example 1 8 | ``` 9 | Input: Array=[0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1], k=2 10 | Output: 6 11 | Explanation: Replace the '0' at index 5 and 8 to have the longest contiguous subarray of 1s having length 6. 12 | ``` 13 | 14 | #### Example 2 15 | ``` 16 | Input: Array=[0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1], k=3 17 | Output: 9 18 | Explanation: Replace the '0' at index 6, 9, and 10 to have the longest contiguous subarray of 1s having length 9. 19 | ``` 20 | 21 | 22 | -------------------------------------------------------------------------------- /patterns/src/1_sliding_window/longest_substr_with_distinct_chars/README.md: -------------------------------------------------------------------------------- 1 | # Longest Substring with Distinct Characters (hard) ✩ 2 | 3 | Given a string, find the length of the longest substring, which has all distinct characters. 4 | 5 | 6 | #### Example 1 7 | ``` 8 | Input: String="aabccbb" 9 | Output: 3 10 | Explanation: The longest substring with distinct characters is "abc". 11 | ``` 12 | 13 | #### Example 2 14 | ``` 15 | Input: String="abbbb" 16 | Output: 2 17 | Explanation: The longest substring with distinct characters is "ab". 18 | ``` 19 | 20 | #### Example 3 21 | ``` 22 | Input: String="abccde" 23 | Output: 3 24 | Explanation: Longest substrings with distinct characters are "abc" & "cde". 25 | ``` 26 | 27 | -------------------------------------------------------------------------------- /patterns/src/1_sliding_window/maximum_sum_subarray_of_size_K/README.md: -------------------------------------------------------------------------------- 1 | # Maximum Sum Subarray of Size K (easy) ✩ 2 | 3 | Given an array of positive numbers and a positive number ‘k,’ find the maximum sum of any contiguous subarray of size ‘k’. 4 | 5 | 6 | ### Example 1 7 | Input: [2, 1, 5, 1, 3, 2], k=3 8 | Output: 9 9 | Explanation: Subarray with maximum sum is [5, 1, 3]. 10 | 11 | ### Example 2 12 | Input: [2, 3, 4, 1, 5], k=2 13 | Output: 7 14 | Explanation: Subarray with maximum sum is [3, 4]. 15 | 16 | -------------------------------------------------------------------------------- /patterns/src/1_sliding_window/smallest_window_containing_substr/README.md: -------------------------------------------------------------------------------- 1 | # Permutation in a String (hard) ✩ 2 | 3 | Given a string and a pattern, find the smallest substring in the given 4 | string which has all the characters of the given pattern. 5 | 6 | #### Example 1 7 | Input: String="aabdec", Pattern="abc" 8 | Output: "abdec" 9 | Explanation: The smallest substring having all characters of the pattern is "abdec" 10 | 11 | #### Example 2 12 | Input: String="abdbca", Pattern="abc" 13 | Output: "bca" 14 | Explanation: The smallest substring having all characters of the pattern is "bca". 15 | 16 | #### Example 3 17 | Input: String="adcad", Pattern="abc" 18 | Output: "" 19 | Explanation: No substring in the given string has all characters of the pattern. 20 | -------------------------------------------------------------------------------- /patterns/src/1_sliding_window/subarrays_with_product_less_than_target/README.md: -------------------------------------------------------------------------------- 1 | # Subarrays with Product Less than a Target (medium) ✩ 2 | 3 | Given an array with positive numbers and a positive target number, 4 | find all of its contiguous subarrays whose product is less than the target number. 5 | 6 | ### Example 1 7 | Input: [2, 5, 3, 10], target=30 8 | Output: [2], [5], [2, 5], [3], [5, 3], [10] 9 | Explanation: There are six contiguous subarrays whose product is less than the target. 10 | 11 | 12 | ### Example 2 13 | Input: [8, 2, 6, 5], target=50 14 | Output: [8], [2], [8, 2], [6], [2, 6], [5], [6, 5] 15 | Explanation: There are seven contiguous subarrays whose product is less than the target. 16 | 17 | -------------------------------------------------------------------------------- /patterns/src/1_sliding_window/words_concatenation/README.MD: -------------------------------------------------------------------------------- 1 | # Words Concatenation (hard) ✩ 2 | 3 | Given a string and a list of words, find all the starting indices of substrings 4 | in the given string that are a concatenation of all the given words exactly once 5 | without any overlapping of words. It is given that all words are of the same length. 6 | 7 | #### Example 1 8 | Input: String="catfoxcat", Words=["cat", "fox"] 9 | Output: [0, 3] 10 | Explanation: The two substring containing both the words are "catfox" & "foxcat". 11 | 12 | #### Example 2 13 | Input: String="catcatfoxfox", Words=["cat", "fox"] 14 | Output: [3] 15 | Explanation: The only substring containing both the words is "catfox". 16 | 17 | -------------------------------------------------------------------------------- /patterns/src/1_sliding_window/words_concatenation/find_word_concatenation.py: -------------------------------------------------------------------------------- 1 | def find_word_concatenation(str, words): 2 | result_indices = [] 3 | 4 | return result_indices 5 | 6 | print(find_word_concatenation("catfoxcat", ["cat", "fox"])) 7 | print(find_word_concatenation("catcatfoxfox", ["cat", "fox"])) -------------------------------------------------------------------------------- /patterns/src/2_two_pointers/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/src/2_two_pointers/README.md -------------------------------------------------------------------------------- /patterns/src/2_two_pointers/dutch_national_flag/README.md: -------------------------------------------------------------------------------- 1 | # Dutch National Flag Problem (medium) ✩ 2 | 3 | Given an array containing 0s, 1s and 2s, sort the array in-place. 4 | You should treat numbers of the array as objects, hence, we can’t count 0s, 1s, and 2s to recreate the array. 5 | 6 | The flag of the Netherlands consists of three colors: 7 | red, white and blue; and since our input array also consists of 8 | three different numbers that is why it is called Dutch National Flag problem. 9 | 10 | ### Example 1 11 | ``` 12 | Input: [1, 0, 2, 1, 0] 13 | Output: [0, 0, 1, 1, 2] 14 | ``` 15 | 16 | 17 | ### Example 2 18 | ``` 19 | Input: [2, 2, 0, 1, 2, 0] 20 | Output: [0, 0, 1, 2, 2, 2,] 21 | ``` 22 | 23 | -------------------------------------------------------------------------------- /patterns/src/2_two_pointers/pair_with_target_sum/README.md: -------------------------------------------------------------------------------- 1 | # Pair with Target Sum (easy) ✩ 2 | 3 | Given an array of sorted numbers and a target sum, find a pair in the array whose sum is equal to the given target. 4 | 5 | Write a function to return the indices of the two numbers (i.e. the pair) such that they add up to the given target 6 | 7 | 8 | ### Example 1 9 | ``` 10 | Input: [1, 2, 3, 4, 6], target=6 11 | Output: [1, 3] 12 | Explanation: The numbers at index 1 and 3 add up to 6: 2+4=6 13 | ``` 14 | 15 | ### Example 2 16 | ``` 17 | Input: [2, 5, 9, 11], target=11 18 | Output: [0, 2] 19 | Explanation: The numbers at index 0 and 2 add up to 11: 2+9=11 20 | ``` 21 | 22 | -------------------------------------------------------------------------------- /patterns/src/2_two_pointers/quadruple_sum_to_targets.py/README.md: -------------------------------------------------------------------------------- 1 | # Quadruple Sum to Target (medium) ✩ 2 | 3 | Given an array of unsorted numbers and a target number, 4 | find all unique quadruplets in it, whose sum is equal to the target number. 5 | 6 | 7 | ### Example 1 8 | Input: [4, 1, 2, -1, 1, -3], target=1 9 | Output: [-3, -1, 1, 4], [-3, 1, 1, 2] 10 | Explanation: Both the quadruplets add up to the target. 11 | 12 | ### Example 2 13 | Input: [2, 0, -1, 1, -2, 2], target=2 14 | Output: [-2, 0, 2, 2], [-1, 0, 1, 2] 15 | Explanation: Both the quadruplets add up to the target. 16 | 17 | -------------------------------------------------------------------------------- /patterns/src/2_two_pointers/remove_duplicates/README.md: -------------------------------------------------------------------------------- 1 | # Remove Duplicates (easy) ✩ 2 | 3 | Given an array of sorted numbers, remove all duplicates from it. You should not use any extra space; 4 | 5 | after removing the duplicates in-place return the length of the subarray that has no duplicate in it. 6 | 7 | 8 | ### Example 1 9 | ``` 10 | Input: [2, 3, 3, 3, 6, 9, 9] 11 | Output: 4 12 | Explanation: The first four elements after removing the duplicates will be [2, 3, 6, 9]. 13 | ``` 14 | 15 | ### Example 2 16 | ``` 17 | Input: [2, 2, 2, 11] 18 | Output: 2 19 | Explanation: The first two elements after removing the duplicates will be [2, 11]. 20 | ``` 21 | 22 | -------------------------------------------------------------------------------- /patterns/src/2_two_pointers/remove_duplicates/remove_duplicates.py: -------------------------------------------------------------------------------- 1 | #Time complexity for this algorithm is O(N) 2 | #Space complexity is O(1) 3 | def remove_duplicates(nums): 4 | l, r, n = 0, 1, len(nums) 5 | while r < n: 6 | if nums[l] == nums[r]: 7 | r += 1 8 | else: 9 | nums[l+1] = nums[r] 10 | l += 1 11 | r += 1 12 | return l + 1 13 | 14 | print(remove_duplicates([2, 3, 3, 3, 6, 9, 9])) #Output 4 : because first four elements after removing the duplicates will be [2, 3, 6, 9] 15 | print(remove_duplicates([2, 2, 2, 11])) # Output 2 : because first two elements after removing the duplicates will be [2, 11] -------------------------------------------------------------------------------- /patterns/src/2_two_pointers/remove_keys/README.md: -------------------------------------------------------------------------------- 1 | # Remove Keys (easy) ✩ 2 | 3 | Given an unsorted array of numbers and a target ‘key’, 4 | remove all instances of ‘key’ in-place and return the new length of the array. 5 | 6 | 7 | ### Example 1 8 | Input: [3, 2, 3, 6, 3, 10, 9, 3], Key=3 9 | Output: 4 10 | Explanation: The first four elements after removing every 'Key' will be [2, 6, 10, 9]. 11 | 12 | ### Example 2 13 | Input: [2, 11, 2, 2, 1], Key=2 14 | Output: 2 15 | Explanation: The first two elements after removing every 'Key' will be [11, 1]. 16 | 17 | 18 | -------------------------------------------------------------------------------- /patterns/src/2_two_pointers/remove_keys/remove_keys.py: -------------------------------------------------------------------------------- 1 | #Time complexity for this algorithm is O(N) 2 | #Space complexity is O(1) 3 | def remove_keys(arr, key): 4 | next_element = 0 5 | 6 | for i in range(len(arr)): 7 | if arr[i] != key: 8 | arr[next_element] = arr[i] 9 | next_element += 1 10 | 11 | return next_element 12 | 13 | 14 | print(remove_keys([3, 2, 3, 6, 3, 10, 9, 3], 3)) #Output: 4 15 | print(remove_keys([2, 11, 2, 2, 1], 2)) #Output: 2 16 | 17 | -------------------------------------------------------------------------------- /patterns/src/2_two_pointers/square_sorted_array/README.md: -------------------------------------------------------------------------------- 1 | # Squaring a Sorted Array (easy) ✩ 2 | 3 | Given a sorted array, create a new array containing squares of all the numbers of the input array in the sorted order. 4 | 5 | 6 | ### Example 1 7 | ``` 8 | Input: [-2, -1, 0, 2, 3] 9 | Output: [0, 1, 4, 4, 9] 10 | ``` 11 | 12 | ### Example 2 13 | ``` 14 | Input: [-3, -1, 0, 1, 2] 15 | Output: [0, 1, 1, 4, 9] 16 | ``` 17 | 18 | -------------------------------------------------------------------------------- /patterns/src/2_two_pointers/subarrays_with_product_less_than_target/README.md: -------------------------------------------------------------------------------- 1 | # Subarrays with Product Less than a Target (medium) ✩ 2 | 3 | Given an array with positive numbers and a positive target number, 4 | find all of its contiguous subarrays whose product is less than the target number. 5 | 6 | ### Example 1 7 | ``` 8 | Input: [2, 5, 3, 10], target=30 9 | Output: [2], [5], [2, 5], [3], [5, 3], [10] 10 | Explanation: There are six contiguous subarrays whose product is less than the target. 11 | ``` 12 | 13 | 14 | ### Example 2 15 | ``` 16 | Input: [8, 2, 6, 5], target=50 17 | Output: [8], [2], [8, 2], [6], [2, 6], [5], [6, 5] 18 | Explanation: There are seven contiguous subarrays whose product is less than the target. 19 | ``` 20 | 21 | -------------------------------------------------------------------------------- /patterns/src/2_two_pointers/triplet_sum_to_zero/README.md: -------------------------------------------------------------------------------- 1 | # Triplet Sum to Zero (medium) ✩ 2 | 3 | Given an array of unsorted numbers, find all unique triplets in it that add up to zero. 4 | 5 | ### Example 1 6 | ``` 7 | Input: [-3, 0, 1, 2, -1, 1, -2] 8 | Output: [-3, 1, 2], [-2, 0, 2], [-2, 1, 1], [-1, 0, 1] 9 | Explanation: There are four unique triplets whose sum is equal to zero. 10 | ``` 11 | 12 | ### Example 2 13 | ``` 14 | Input: [-5, 2, -1, -2, 3] 15 | Output: [[-5, 2, 3], [-2, -1, 3]] 16 | Explanation: There are two unique triplets whose sum is equal to zero. 17 | ``` 18 | 19 | -------------------------------------------------------------------------------- /patterns/src/3_fast_and_slow_pointers/cycle_in_circular_array/cycle_in_circular_array.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/src/3_fast_and_slow_pointers/cycle_in_circular_array/cycle_in_circular_array.py -------------------------------------------------------------------------------- /patterns/src/3_fast_and_slow_pointers/length_of_cycle/README.md: -------------------------------------------------------------------------------- 1 | # Length of LinkedList Cycle (easy) ✩ 2 | 3 | Given the head of a LinkedList with a cycle, find the length of the cycle -------------------------------------------------------------------------------- /patterns/src/3_fast_and_slow_pointers/linkedlist_cycle/README.md: -------------------------------------------------------------------------------- 1 | # LinkedList Cycle (easy) ✩ 2 | 3 | Given the head of a Singly LinkedList, write a function to determine if the LinkedList has a cycle in it or not. 4 | 5 | 6 | -------------------------------------------------------------------------------- /patterns/src/3_fast_and_slow_pointers/middle_of_linkedlist/README.md: -------------------------------------------------------------------------------- 1 | # Middle of the LinkedList (easy) ✩ 2 | 3 | Given the head of a Singly LinkedList, write a method to return the middle node of the LinkedList. 4 | 5 | If the total number of nodes in the LinkedList is even, return the second middle node. 6 | 7 | #### Example 1 8 | Input: 1 -> 2 -> 3 -> 4 -> 5 -> null 9 | Output: 3 10 | 11 | #### Example 2 12 | Input: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> null 13 | Output: 4 14 | 15 | #### Example 3 16 | Input: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> null 17 | Output: 4 18 | 19 | 20 | -------------------------------------------------------------------------------- /patterns/src/3_fast_and_slow_pointers/palindrome_linkedlist/README.md: -------------------------------------------------------------------------------- 1 | # Palindrome LinkedList (medium) ✩ 2 | 3 | Given the head of a Singly LinkedList, write a method to check if the LinkedList is a palindrome or not. 4 | 5 | Your algorithm should use constant space and the input LinkedList should be in the 6 | original form once the algorithm is finished. 7 | The algorithm should have O(N) time complexity where ‘N’ is the number of nodes in the LinkedList. 8 | 9 | #### Example 1 10 | Input: 2 -> 4 -> 6 -> 4 -> 2 -> null 11 | Output: true 12 | 13 | #### Example 2 14 | Input: 2 -> 4 -> 6 -> 4 -> 2 -> 2 -> null 15 | Output: false 16 | -------------------------------------------------------------------------------- /patterns/src/3_fast_and_slow_pointers/start_of_linkedlist_cycle/README.md: -------------------------------------------------------------------------------- 1 | # Start of LinkedList Cycle (medium) ✩ 2 | 3 | Given the head of a Singly LinkedList that contains a cycle, write a function to find the starting node of the cycle. 4 | 5 | 6 | ![Start of linkedlist cycle explanation](./../../../assets/linkedlist_cycle_start.png) 7 | 8 | 9 | -------------------------------------------------------------------------------- /patterns/src/4_merge_intervals/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/david-legend/python-algorithms/4e45c5beee1fc56fe976d6ad1af58e2bd94aa4a3/patterns/src/4_merge_intervals/README.md -------------------------------------------------------------------------------- /patterns/src/4_merge_intervals/employee_free_time/employee_free_time.py: -------------------------------------------------------------------------------- 1 | def find_employee_free_time(schedules): 2 | result, merge = [], [] 3 | 4 | for schedule in schedules: 5 | for interval in schedule: 6 | merge.append(interval) 7 | 8 | merge.sort(key=lambda x : x[0]) 9 | start, end = 0, 1 10 | for i in range(1, len(merge)): 11 | prev = i - 1 12 | if merge[i][start] > merge[prev][end]: 13 | result.append([merge[prev][end], merge[i][start]]) 14 | 15 | return result 16 | 17 | 18 | print(find_employee_free_time([[[1,3], [5,6]], [[2,3], [6,8]]])) 19 | print(find_employee_free_time([[[1,3], [9,12]], [[2,4]], [[6,8]]])) 20 | print(find_employee_free_time([[[1,3]], [[2,4]], [[3,5], [7,9]]])) -------------------------------------------------------------------------------- /patterns/src/4_merge_intervals/find_intervals/README.md: -------------------------------------------------------------------------------- 1 | # Find Intervals (medium) ✩ 2 | 3 | Given a set of intervals, find out if any two intervals overlap. 4 | 5 | 6 | #### Example 1 7 | ``` 8 | Intervals: [[1,4], [2,5], [7,9]] 9 | Output: true 10 | Explanation: Intervals [1,4] and [2,5] overlap 11 | ``` 12 | 13 | 14 | #### Example 2 15 | ``` 16 | Intervals: [[6,7], [9,12]] 17 | Output: false 18 | Explanation: Intervals [6,7] and [9,12] do not overlap 19 | ``` -------------------------------------------------------------------------------- /patterns/src/4_merge_intervals/find_intervals/find_interval.py: -------------------------------------------------------------------------------- 1 | def find_interval(intervals): 2 | if len(intervals) < 2: 3 | return False 4 | 5 | intervals.sort(key=lambda x: x[0]) 6 | end = intervals[0][1] 7 | 8 | for i in range(1, len(intervals)): 9 | interval = intervals[i] 10 | if interval[0] <= end: 11 | return True 12 | else: 13 | end = interval[1] 14 | 15 | return False 16 | 17 | 18 | print(find_interval([[1, 4], [2, 5], [7, 9]])) 19 | print(find_interval([[6,7], [9,12]])) -------------------------------------------------------------------------------- /patterns/src/4_merge_intervals/intervals_intersection/README.md: -------------------------------------------------------------------------------- 1 | # Intervals Intersection (medium) ✩ 2 | 3 | Given two lists of intervals, find the intersection of these two lists. 4 | Each list consists of disjoint intervals sorted on their start time. 5 | 6 | 7 | #### Example 1 8 | ``` 9 | Input: arr1=[[1, 3], [5, 6], [7, 9]], arr2=[[2, 3], [5, 7]] 10 | Output: [2, 3], [5, 6], [7, 7] 11 | Explanation: The output list contains the common intervals between the two lists. 12 | ``` 13 | 14 | #### Example 2 15 | ``` 16 | Input: arr1=[[1, 3], [5, 7], [9, 12]], arr2=[[5, 10]] 17 | Output: [5, 7], [9, 10] 18 | Explanation: The output list contains the common intervals between the two lists. 19 | ``` 20 | -------------------------------------------------------------------------------- /patterns/src/5_cyclic_sort/find_all_duplicate_numbers/README.md: -------------------------------------------------------------------------------- 1 | # Find all Duplicate Numbers (easy) ✩ 2 | 3 | We are given an unsorted array containing ‘n’ numbers taken from the range 1 to ‘n’. 4 | The array has some numbers appearing twice, find all these duplicate numbers without using any extra space. 5 | 6 | #### Example 1 7 | Input: [3, 4, 4, 5, 5] 8 | Output: [4, 5] 9 | 10 | #### Example 2 11 | Input: [5, 4, 7, 2, 3, 5, 3] 12 | Output: [3, 5] 13 | 14 | -------------------------------------------------------------------------------- /patterns/src/5_cyclic_sort/find_all_missing_numbers/README.md: -------------------------------------------------------------------------------- 1 | # Find all missing numbers (easy) ✩ 2 | 3 | We are given an unsorted array containing numbers taken from the range 1 to ‘n’. 4 | The array can have duplicates, which means some numbers will be missing. Find all those missing numbers. 5 | 6 | #### Example 1 7 | Input: [2, 3, 1, 8, 2, 3, 5, 1] 8 | Output: 4, 6, 7 9 | Explanation: The array should have all numbers from 1 to 8, due to duplicates 4, 6, and 7 are missing. 10 | 11 | #### Example 2 12 | Input: [2, 4, 1, 2] 13 | Output: 3 14 | 15 | #### Example 3 16 | Input: [2, 3, 2, 1] 17 | Output: 4 -------------------------------------------------------------------------------- /patterns/src/5_cyclic_sort/find_corrupt_pair/README.md: -------------------------------------------------------------------------------- 1 | # Find the Corrupt Pair (easy) ✩ 2 | 3 | We are given an unsorted array containing ‘n’ numbers taken from the range 1 to ‘n’. 4 | The array originally contained all the numbers from 1 to ‘n’, 5 | but due to a data error, one of the numbers got duplicated 6 | which also resulted in one number going missing. Find both these numbers. 7 | 8 | #### Example 1 9 | Input: [3, 1, 2, 5, 2] 10 | Output: [2, 4] 11 | Explanation: '2' is duplicated and '4' is missing. 12 | 13 | #### Example 2 14 | Input: [3, 1, 2, 3, 6, 4] 15 | Output: [3, 5] 16 | Explanation: '3' is duplicated and '5' is missing. 17 | 18 | -------------------------------------------------------------------------------- /patterns/src/5_cyclic_sort/find_corrupt_pair/find_corrupt_pair.py: -------------------------------------------------------------------------------- 1 | def find_corrupt_pair(nums): 2 | i, n = 0, len(nums) 3 | 4 | while i < len(nums): 5 | j = nums[i] - 1 6 | if nums[i] != nums[j]: 7 | nums[i], nums[j] = nums[j], nums[i] 8 | else: 9 | i += 1 10 | 11 | for i in range(n): 12 | if nums[i] != i+1: 13 | return [nums[i], i + 1] 14 | 15 | return [-1, -1] 16 | 17 | 18 | print(find_corrupt_pair([3, 1, 2, 5, 2])) 19 | print(find_corrupt_pair([3, 1, 2, 3, 6, 4])) 20 | -------------------------------------------------------------------------------- /patterns/src/5_cyclic_sort/find_duplicate_number/README.md: -------------------------------------------------------------------------------- 1 | # Find the Duplicate Number (easy) ✩ 2 | 3 | We are given an unsorted array containing ‘n+1’ numbers taken from the range 1 to ‘n’. 4 | The array has only one duplicate but it can be repeated multiple times. 5 | Find that duplicate number without using any extra space. 6 | You are, however, allowed to modify the input array. 7 | 8 | #### Example 1 9 | Input: [1, 4, 4, 3, 2] 10 | Output: 4 11 | 12 | #### Example 2 13 | Input: [2, 1, 3, 3, 5, 4] 14 | Output: 3 15 | 16 | #### Example 3 17 | Input: [2, 4, 1, 4, 4] 18 | Output: 4 19 | -------------------------------------------------------------------------------- /patterns/src/5_cyclic_sort/find_duplicate_number/find_duplicate_number.py: -------------------------------------------------------------------------------- 1 | # Time complexity 2 | # The time complexity of the algorithm is O(n). 3 | 4 | # Space complexity 5 | # The algorithm runs in constant space O(1) but modifies the input array. 6 | 7 | def find_duplicate(nums): 8 | i, n = 0, len(nums) 9 | 10 | while i < n: 11 | if nums[i] != i+1: 12 | j = nums[i] - 1 13 | if nums[i] != nums[j]: 14 | nums[i], nums[j] = nums[j], nums[i] 15 | else: 16 | return nums[i] 17 | else: 18 | i += 1 19 | 20 | return -1 21 | 22 | 23 | print(find_duplicate([1, 4, 4, 3, 2])) 24 | print(find_duplicate([2, 1, 3, 3, 5, 4])) 25 | print(find_duplicate([2, 4, 1, 4, 4])) -------------------------------------------------------------------------------- /patterns/src/5_cyclic_sort/find_first_K_missing_positive_numbers/README.md: -------------------------------------------------------------------------------- 1 | # Find the First K Missing Positive Numbers (hard) ✩ 2 | 3 | Given an unsorted array containing numbers and a number ‘k’, 4 | find the first ‘k’ missing positive numbers in the array. 5 | 6 | #### Example 1 7 | Input: [3, -1, 4, 5, 5], k=3 8 | Output: [1, 2, 6] 9 | Explanation: The smallest missing positive numbers are 1, 2 and 6. 10 | 11 | #### Example 2 12 | Input: [2, 3, 4], k=3 13 | Output: [1, 5, 6] 14 | Explanation: The smallest missing positive numbers are 1, 5 and 6. 15 | 16 | #### Example 3 17 | Input: [-2, -3, 4], k=2 18 | Output: [1, 2] 19 | Explanation: The smallest missing positive numbers are 1 and 2. 20 | -------------------------------------------------------------------------------- /patterns/src/5_cyclic_sort/find_missing_number/README.md: -------------------------------------------------------------------------------- 1 | # Find the missing number (easy) ✩ 2 | 3 | We are given an array containing ‘n’ distinct numbers taken from the range 0 to ‘n’. 4 | Since the array has only ‘n’ numbers out of the total ‘n+1’ numbers, find the missing number. 5 | 6 | #### Example 1 7 | Input: [4, 0, 3, 1] 8 | Output: 2 9 | 10 | #### Example 2 11 | Input: [8, 3, 5, 2, 4, 6, 0, 1] 12 | Output: 7 13 | -------------------------------------------------------------------------------- /patterns/src/5_cyclic_sort/find_missing_number/find_missing_number.py: -------------------------------------------------------------------------------- 1 | def find_missing_number(nums): 2 | i, n = 0, len(nums) 3 | while i < n: 4 | j = nums[i] 5 | if nums[i] < n and nums[i] != nums[j]: 6 | nums[i], nums[j] = nums[j], nums[i] # swap 7 | else: 8 | i += 1 9 | 10 | # find the first number missing from its index, that will be our required number 11 | for i in range(n): 12 | if nums[i] != i: 13 | return i 14 | 15 | return n 16 | 17 | print(find_missing_number([4, 0, 3, 1])) 18 | print(find_missing_number([8, 3, 5, 2, 4, 6, 0, 1])) -------------------------------------------------------------------------------- /patterns/src/5_cyclic_sort/find_smallest_missing_positive_number/README.md: -------------------------------------------------------------------------------- 1 | # Find the Smallest Missing Positive Number (medium) ✩ 2 | 3 | Given an unsorted array containing numbers, 4 | find the smallest missing positive number in it. 5 | 6 | #### Example 1 7 | Input: [-3, 1, 5, 4, 2] 8 | Output: 3 9 | Explanation: The smallest missing positive number is '3' 10 | 11 | #### Example 2 12 | Input: [3, -2, 0, 1, 2] 13 | Output: 4 14 | 15 | #### Example 3 16 | Input: [3, 2, 5, 1] 17 | Output: 4 18 | -------------------------------------------------------------------------------- /patterns/src/6_in_place_reversal_of_linkedlist/README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | In a lot of problems, we are asked to reverse the links between a set of nodes of a LinkedList. 4 | Often, the constraint is that we need to do this in-place, 5 | i.e., using the existing node objects and without using extra memory. 6 | 7 | In-place Reversal of a LinkedList pattern describes an efficient way to solve the above problem. -------------------------------------------------------------------------------- /patterns/src/6_in_place_reversal_of_linkedlist/reverse_alternating_K-element_sub-list/README.md: -------------------------------------------------------------------------------- 1 | # Reverse alternating K-element Sub-list (medium) ✩ 2 | 3 | Given the head of a LinkedList and a number ‘k’, reverse every alternating ‘k’ sized sub-list starting from the head. 4 | 5 | If, in the end, you are left with a sub-list with less than ‘k’ elements, reverse it too. 6 | 7 | ![Reverse a LinkedList explanation](./../../../assets/reverse_alternating_k-element_sublist.png) -------------------------------------------------------------------------------- /patterns/src/6_in_place_reversal_of_linkedlist/reverse_every_k_sublist/README.md: -------------------------------------------------------------------------------- 1 | # Reverse every K-element Sub-list (medium) ✩ 2 | 3 | Given the head of a LinkedList and a number ‘k’, reverse every ‘k’ sized sub-list starting from the head. 4 | 5 | If, in the end, you are left with a sub-list with less than ‘k’ elements, reverse it too. 6 | 7 | ![Reverse a LinkedList explanation](./../../../assets/reverse_k_sublist.png) -------------------------------------------------------------------------------- /patterns/src/6_in_place_reversal_of_linkedlist/reverse_linkedlist/README.md: -------------------------------------------------------------------------------- 1 | # Reverse a LinkedList (easy) ✩ 2 | 3 | Given the head of a Singly LinkedList, reverse the LinkedList. 4 | Write a function to return the new head of the reversed LinkedList. 5 | 6 | ![Reverse a LinkedList explanation](./../../../assets/reverse_linkedlist.png) -------------------------------------------------------------------------------- /patterns/src/6_in_place_reversal_of_linkedlist/reverse_sublist/README.md: -------------------------------------------------------------------------------- 1 | # Reverse a Sub-list (medium) ✩ 2 | 3 | Given the head of a LinkedList and two positions ‘p’ and ‘q’, 4 | reverse the LinkedList from position ‘p’ to ‘q’. 5 | 6 | ![Reverse a LinkedList explanation](./../../../assets/reverse_sublist.png) -------------------------------------------------------------------------------- /patterns/src/6_in_place_reversal_of_linkedlist/rotate_linkedlist/README.md: -------------------------------------------------------------------------------- 1 | # Rotate Linkedlist (medium) ✩ 2 | 3 | Given the head of a Singly LinkedList and a number ‘k’, rotate the LinkedList to the right by ‘k’ nodes. 4 | 5 | ### Example 1 6 | 7 | ![Reverse a LinkedList explanation](./../../../assets/rotate_linkedlist_eg1.png) 8 | 9 | ### Example 2 10 | 11 | ![Reverse a LinkedList explanation](./../../../assets/rotate_linkedlist_eg2.png) 12 | -------------------------------------------------------------------------------- /patterns/src/7_tree_breath_first_search/README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | This pattern is based on the Breadth First Search (BFS) technique to traverse a tree. 4 | 5 | Any problem involving the traversal of a tree in a level-by-level order can be efficiently 6 | solved using this approach. We will use a Queue to keep track of all the nodes of a level 7 | before we jump onto the next level. 8 | This also means that the space complexity of the algorithm will be O(W), 9 | where ‘W’ is the maximum number of nodes on any level. -------------------------------------------------------------------------------- /patterns/src/7_tree_breath_first_search/connect_all_level_order_siblings/README.md: -------------------------------------------------------------------------------- 1 | # Connect All Level Order Siblings (medium)✩ 2 | 3 | Given a binary tree, connect each node with its level order successor. 4 | The last node of each level should point to the first node of the next level. 5 | 6 | ![Connect All Level Order Siblings Example 1](./../../../assets/connect_all_level_order_siblings_1.png) 7 | 8 | ![Connect All Level Order Siblings Example 2](./../../../assets/connect_all_level_order_siblings_2.png) 9 | 10 | -------------------------------------------------------------------------------- /patterns/src/7_tree_breath_first_search/connect_level_order_siblings/README.md: -------------------------------------------------------------------------------- 1 | # Connect Level Order Siblings (medium)✩ 2 | 3 | Given a binary tree, connect each node with its level order successor. 4 | The last node of each level should point to a null node. 5 | 6 | ![Connect Level Order Siblings Example 1](./../../../assets/level_order_siblings_1.png) 7 | 8 | ![Connect Level Order Siblings Example 2](./../../../assets/level_order_siblings_2.png) 9 | 10 | -------------------------------------------------------------------------------- /patterns/src/7_tree_breath_first_search/largest_value_on_each_level/README.md: -------------------------------------------------------------------------------- 1 | # Largest Value on each Level in a Binary Tree (easy) ✩ 2 | 3 | Find the largest value on each level of a binary tree. 4 | 5 | -------------------------------------------------------------------------------- /patterns/src/7_tree_breath_first_search/left_view_of_tree/README.md: -------------------------------------------------------------------------------- 1 | # Right View of a Binary Tree (easy)✩ 2 | 3 | Given a binary tree, return an array containing nodes in its left view. 4 | The left view of a binary tree is the set of nodes visible when the tree is seen from the left side. 5 | 6 | -------------------------------------------------------------------------------- /patterns/src/7_tree_breath_first_search/level_averages_in_binary_tree/README.md: -------------------------------------------------------------------------------- 1 | # Level Averages in a Binary Tree (easy) ✩ 2 | 3 | Given a binary tree, populate an array to represent the averages of all of its levels. 4 | 5 | ![Level Averages in a Binary Tree Example 1](./../../../assets/level_averages_eg1.png) 6 | 7 | ![Level Averages in a Binary Tree Example 2](./../../../assets/level_averages_eg2.png) 8 | 9 | -------------------------------------------------------------------------------- /patterns/src/7_tree_breath_first_search/level_order_successor/README.md: -------------------------------------------------------------------------------- 1 | # Level Order Successor (easy)✩ 2 | 3 | Given a binary tree and a node, find the level order successor of the given node in the tree. 4 | The level order successor is the node that appears right after the given node in the level order traversal. 5 | 6 | ![Level Order Successor Example 1](./../../../assets/level_order_successor_1.png) 7 | 8 | ![Level Order Successor Example 2](./../../../assets/level_order_successor_2.png) 9 | 10 | ![Level Order Successor Example 3](./../../../assets/level_order_successor_3.png) 11 | 12 | -------------------------------------------------------------------------------- /patterns/src/7_tree_breath_first_search/level_order_traversal/README.md: -------------------------------------------------------------------------------- 1 | # Binary Tree Level Order Traversal (easy) ✩ 2 | 3 | Given a binary tree, populate an array to represent its level-by-level traversal. 4 | You should populate the values of all nodes of each level from left to right in separate sub-arrays. 5 | 6 | ![Binary Tree Level Order Traversal Example 1](./../../../assets/bt_level_order_traversal_eg1.png) 7 | 8 | ![Binary Tree Level Order Traversal Example 2](./../../../assets/bt_level_order_traversal_eg2.png) 9 | 10 | -------------------------------------------------------------------------------- /patterns/src/7_tree_breath_first_search/max_depth_of_tree/README.md: -------------------------------------------------------------------------------- 1 | # Minimum Depth of a Binary Tree (easy)✩ 2 | 3 | Given a binary tree, find its maximum depth (or height) 4 | 5 | -------------------------------------------------------------------------------- /patterns/src/7_tree_breath_first_search/min_depth_of_binary_tree/README.md: -------------------------------------------------------------------------------- 1 | # Minimum Depth of a Binary Tree (easy)✩ 2 | 3 | Find the minimum depth of a binary tree. The minimum depth is the number of nodes 4 | along the shortest path from the root node to the nearest leaf node. 5 | 6 | ![Minimum Depth of a Binary Tree Example 1](./../../../assets/min_depth_of_binary_tree_eg1.png) 7 | 8 | ![Minimum Depth of a Binary Tree Example 2](./../../../assets/min_depth_of_binary_tree_eg2.png) 9 | 10 | -------------------------------------------------------------------------------- /patterns/src/7_tree_breath_first_search/reverse_level_order_traversal/README.md: -------------------------------------------------------------------------------- 1 | # Reverse Level Order Traversal (easy) ✩ 2 | 3 | Given a binary tree, populate an array to represent its level-by-level traversal in reverse order, 4 | i.e., the lowest level comes first. 5 | You should populate the values of all nodes in each level from left to right in separate sub-arrays. 6 | 7 | ![Binary Tree Reverse Level Order Traversal Example 1](./../../../assets/bt_reverse_level_order_traversal_eg1.png) 8 | 9 | ![Binary Tree Reverse Level Order Traversal Example 2](./../../../assets/bt_reverse_level_order_traversal_eg2.png) 10 | 11 | -------------------------------------------------------------------------------- /patterns/src/7_tree_breath_first_search/right_view_of_binary_tree/README.md: -------------------------------------------------------------------------------- 1 | # Right View of a Binary Tree (easy)✩ 2 | 3 | Given a binary tree, return an array containing nodes in its right view. 4 | The right view of a binary tree is the set of nodes visible when the tree is seen from the right side. 5 | 6 | ![Minimum Depth of a Binary Tree Example 1](./../../../assets/right_view_of_binary_tree_1.png) 7 | 8 | ![Minimum Depth of a Binary Tree Example 2](./../../../assets/right_view_of_binary_tree_2.png) 9 | 10 | -------------------------------------------------------------------------------- /patterns/src/7_tree_breath_first_search/zigzag_traversal/README.md: -------------------------------------------------------------------------------- 1 | # Zigzag Traversal (medium) ✩ 2 | 3 | Given a binary tree, populate an array to represent its zigzag level order traversal. 4 | You should populate the values of all nodes of the first level from left to right, 5 | then right to left for the next level and keep alternating in the same manner for the following levels. 6 | 7 | ![Binary Tree Reverse Level Order Traversal Example 1](./../../../assets/zigzag_traversal_eg1.png) 8 | 9 | ![Binary Tree Reverse Level Order Traversal Example 2](./../../../assets/zigzag_traversal_eg2.png) 10 | 11 | -------------------------------------------------------------------------------- /patterns/src/8_tree_depth_first_search/README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | This pattern is based on the Depth First Search (DFS) technique to traverse a tree. 4 | 5 | We will be using recursion (or we can also use a stack for the iterative approach) 6 | to keep track of all the previous (parent) nodes while traversing. 7 | This also means that the space complexity of the algorithm will be O(H), 8 | where ‘H’ is the maximum height of the tree. -------------------------------------------------------------------------------- /patterns/src/8_tree_depth_first_search/all_paths_for_a_sum/README.md: -------------------------------------------------------------------------------- 1 | # All Paths for a Sum (medium)✩ 2 | 3 | Given a binary tree and a number ‘S’, find all paths from root-to-leaf 4 | such that the sum of all the node values of each path equals ‘S’. 5 | 6 | ![All Paths for a Sum Example 1](./../../../assets/all_paths_for_sum_1.png) 7 | 8 | ![All Paths for a Sum Example 2](./../../../assets/all_paths_for_sum_2.png) 9 | 10 | -------------------------------------------------------------------------------- /patterns/src/8_tree_depth_first_search/btree_path_sum/README.md: -------------------------------------------------------------------------------- 1 | # Binary Tree Path Sum (easy)✩ 2 | 3 | Given a binary tree and a number ‘S’, find if the tree has a path from 4 | root-to-leaf such that the sum of all the node values of that path equals ‘S’. 5 | 6 | ![Binary Tree Path Sum Example 1](./../../../assets/btree_path_sum_1.png) 7 | 8 | ![Binary Tree Path Sum Example 2](./../../../assets/btree_path_sum_2.png) 9 | 10 | -------------------------------------------------------------------------------- /patterns/src/8_tree_depth_first_search/count_paths_for_sum/README.md: -------------------------------------------------------------------------------- 1 | # Count Paths for a Sum (medium)✩ 2 | 3 | Given a binary tree and a number ‘S’, find all paths in the tree such that 4 | the sum of all the node values of each path equals ‘S’. Please note that the 5 | paths can start or end at any node but all paths must follow direction 6 | from parent to child (top to bottom). 7 | 8 | ![Count Paths for a Sum Example 1](./../../../assets/count_paths_sum_1.png) 9 | 10 | ![Count Paths for a Sum Example 2](./../../../assets/count_paths_sum_2.png) 11 | 12 | -------------------------------------------------------------------------------- /patterns/src/8_tree_depth_first_search/path_with_given_sequence/README.md: -------------------------------------------------------------------------------- 1 | # Path With Given Sequence (medium)✩ 2 | 3 | Given a binary tree and a number sequence, 4 | find if the sequence is present as a root-to-leaf path in the given tree. 5 | 6 | ![Path With Given Sequence Example 1](./../../../assets/path_with_sequence_1.png) 7 | 8 | ![Path With Given Sequence Example 2](./../../../assets/path_with_sequence_2.png) 9 | 10 | -------------------------------------------------------------------------------- /patterns/src/8_tree_depth_first_search/path_with_maximum_sum/README.md: -------------------------------------------------------------------------------- 1 | # Path With Maximum Sum (Hard)✩ 2 | 3 | Find the path with the maximum sum in a given binary tree. 4 | Write a function that returns the maximum sum. 5 | 6 | A path can be defined as a sequence of nodes between any two nodes 7 | and doesn’t necessarily pass through the root. The path must contain at least one node. 8 | 9 | ![Binary Tree Path Sum Example 1](./../../../assets/path_with_max_sum_1.png) 10 | 11 | ![Binary Tree Path Sum Example 2](./../../../assets/path_with_max_sum_2.png) 12 | 13 | -------------------------------------------------------------------------------- /patterns/src/8_tree_depth_first_search/root_to_leaf_paths/README.md: -------------------------------------------------------------------------------- 1 | # Root to Leaf Paths (medium)✩ 2 | 3 | Given a binary tree, return all root-to-leaf paths. 4 | 5 | 6 | -------------------------------------------------------------------------------- /patterns/src/8_tree_depth_first_search/sum_of_path_numbers/README.md: -------------------------------------------------------------------------------- 1 | # Sum of Path Numbers (medium)✩ 2 | 3 | Given a binary tree where each node can only have a digit (0-9) value, 4 | each root-to-leaf path will represent a number. 5 | Find the total sum of all the numbers represented by all paths. 6 | 7 | ![Sum of Path Numbers Example 1](./../../../assets/sum_of_path_numbers_1.png) 8 | 9 | ![Sum of Path Numbers Example 2](./../../../assets/sum_of_path_numbers_2.png) 10 | 11 | -------------------------------------------------------------------------------- /patterns/src/8_tree_depth_first_search/tree_diameter/README.md: -------------------------------------------------------------------------------- 1 | # Tree Diameter (medium)✩ 2 | 3 | Given a binary tree, find the length of its diameter. 4 | The diameter of a tree is the number of nodes on the longest 5 | path between any two leaf nodes. 6 | 7 | The diameter of a tree may or may not pass through the root. 8 | 9 | Note: You can always assume that there are at least two leaf nodes in the given tree. 10 | 11 | ![Binary Tree Path Sum Example 1](./../../../assets/tree_diameter_1.png) 12 | 13 | ![Binary Tree Path Sum Example 2](./../../../assets/tree_diameter_2.png) 14 | 15 | -------------------------------------------------------------------------------- /patterns/src/9_two_heaps/1_median_of_number_stream/README.md: -------------------------------------------------------------------------------- 1 | # Find the Median of a Number Stream (medium)✩ 2 | 3 | Design a class to calculate the median of a number stream. 4 | The class should have the following two methods: 5 | 6 | 1. insertNum(int num): stores the number in the class 7 | 2. findMedian(): returns the median of all numbers inserted in the class 8 | 9 | If the count of numbers inserted in the class is even, the median will be the average of the middle two numbers. 10 | 11 | ![Find the Median of a Number Stream Example 1](./../../../assets/median_of_stream.png) 12 | 13 | -------------------------------------------------------------------------------- /recursion_crash_course/src/2_recursion_with_numbers/2_sum_of_natural_numbers.py: -------------------------------------------------------------------------------- 1 | def sum_natural_numbers(val): 2 | if val <= 1: 3 | return val 4 | 5 | return val + sum_natural_numbers(val - 1) 6 | 7 | 8 | print(sum_natural_numbers(10)) # 55 9 | print(sum_natural_numbers(7)) # 28 -------------------------------------------------------------------------------- /recursion_crash_course/src/3_divide_and_conquer/2_binary_search.py: -------------------------------------------------------------------------------- 1 | def binary_search(nums, left, right, target): 2 | if left > right: 3 | return -1 4 | 5 | mid = (left + right) // 2 6 | 7 | if nums[mid] == target: 8 | return mid 9 | 10 | if target < nums[mid]: 11 | return binary_search(nums, left, mid - 1, target) 12 | 13 | return binary_search(nums, mid + 1, right, target) 14 | 15 | 16 | nums = [-1, 0, 1, 2, 4, 5, 6, 10] 17 | print(binary_search(nums, 0, len(nums) - 1, -1)) #0 18 | print(binary_search(nums, 0, len(nums) - 1, 2)) #3 19 | print(binary_search(nums, 0, len(nums) - 1, 10)) #7 20 | print(binary_search(nums, 0, len(nums) - 1, 5)) #5 --------------------------------------------------------------------------------