├── .gitignore ├── 30_day_challenge ├── 01_single_number.py ├── 02_happy_number.py ├── 03_max_sub_array.py ├── 04_move_zeros.py ├── 05_max_profit.py ├── 06_group_anagram.py ├── 07_count_elements.py ├── 08_middle_node.py ├── 09_backspace_compare.py ├── 10_min_stack.py ├── 11_diameter_of_binary_tree.py ├── 12_last_stone_weight.py ├── 13_contigious_array.py ├── 14_string_shift.py ├── 15_product_except_self.py ├── 16_valid_parenthesis.py ├── 17_number_of_islands.py ├── 18_min_path_sum.py ├── 20_contruct_bst_from_preorder.py ├── 21_left_most_column.py ├── 22_sub_array_sum_equals_k.py ├── 23_bitwise_range_and.py ├── 24_lru_cache.py ├── 25_jump_game.py ├── 27_max_square.py ├── 28_first_unique_num.py └── 30_is_valid_sequence.py ├── algorithms ├── add_strings.py ├── backspace_string_compare.py ├── base_7.py ├── binary_gap.py ├── binary_tree_height.py ├── binary_tree_paths.py ├── bitwise_and_sum.py ├── bitwise_complement.py ├── break_integer.py ├── clone_graph.py ├── compare_version_numbers.py ├── convert_to_hex.py ├── delete_duplicates_from_sorted_list.py ├── design_linked_list.py ├── diagonal_traverse.py ├── diameter_of_tree.py ├── excel_sheet_column_title.py ├── first_missing_positive_int.py ├── first_unique_number.py ├── invert-binary-tree.py ├── is_same_tree.py ├── is_valid_sequence.py ├── k_closest_points_to_origin.py ├── k_diff_pairs_in_an_array.py ├── longest_absolute_file_path.py ├── lru_cache.py ├── math_sqrt.py ├── max_product_of_tree_nums.py ├── max_product_of_word_lengths.py ├── maximum_depth_of_tree.py ├── merge_sorted_lists.py ├── middle_of_linked_list.py ├── min_height_of_binary_tree.py ├── mountain_array.py ├── multiply_strings.py ├── path_sum.py ├── power_of_four.py ├── product_of_array_except_self.py ├── ransom_note.py ├── remove_linked_list_elements.py ├── reverse_words.py ├── rotate_linked_list.py ├── rotated_digits.py ├── search_in_bst.py ├── self_crossing.py ├── sequentials_digits.py ├── smallest_sufficient_team.py ├── sort_characters_by_frequency.py ├── squares_of_sorted_array.go ├── squares_of_sorted_array.py ├── string_compression.py ├── third_max.py ├── uni_valued_binary_tree.py ├── valid_boomerang.py ├── valid_perfect_square.py ├── verify_alien_dictionary.py ├── word_break.py ├── word_break_ii.py ├── word_pattern.py ├── x_of_a_kind_in_a_deck_of_cards.py └── xor-operation-in-an-array.py ├── august_challenge ├── 01_detect_capital.py ├── 03_valid_palindrome.py ├── 04_power_of_four.py ├── 05_add_and_search_words.py └── 06_find_duplicates.py ├── database ├── big_countries.sql ├── combine_two_tables.sql ├── customer_who_never_ordered.sql ├── dublicate_emails.sql ├── employees_earning_more_than_theirs_managers.sql ├── not_boring_movies.sql ├── rising_temperature.sql └── second_highest_salary.sql ├── june_challenge ├── 01_invert_binary_tree.py ├── 02_delete_node_in_linked_list.py ├── 03_two_city_scheduling.py ├── 04_reverse_string.py ├── 05_random_with_weight.py ├── 06_queue_reconstruction_by_height.py ├── 07_coin_change_2.py ├── 08_power_of_two.py ├── 09_is_subsequence.py ├── 10_insert_position.py ├── 11_sort_colors.py ├── 12_randomized_set.py ├── 13_divisible_subset.py ├── 14_cheapest_flight_within_k_stops.py ├── 15_search_in_bst.py ├── 16_validate_ip_address.py ├── 17_surrounded_regions.py ├── 18_h_index.py ├── 19_longest_duplicate_substring.py ├── 20_permutations_sequence.py └── 21_dungeon_game.py ├── may_challenge ├── 01_first_bad_version.py ├── 02_jewels_and_stones.py ├── 03_ransom_note.py ├── 04_number_complement.py ├── 05_first_unique_char.py ├── 06_majority_element.py ├── 07_cousins_in_binary_tree.py ├── 08_check_straight_line.py ├── 09_valid_perfect_square.py ├── 10_town_judge.py ├── 11_flood_fill.py ├── 12_single_in_sorted_array.py ├── 13_remove_k_digits.py ├── 14_implement_trie.py ├── 15_max_circular_subarray.py ├── 16_odd_even_linked_list.py ├── 17_find_anagrams.py ├── 18_permutation_in_string.py ├── 19_online_stock_span.py ├── 20_kth_smallest_in_bst.py ├── 21_count_squares.py ├── 22_sort_chars_by_frequency.py ├── 23_interval_intersection.py ├── 24_bst_from_preorder.py ├── 25_uncrossed_lines.py ├── 26_contiguous_array.py ├── 27_possible_bipartion.py ├── 28_count_bits.py ├── 29_course_schedule.py ├── 30_k_closest_to_origin.py └── 31_edit_distance.py ├── readme.md └── top_interview_questions ├── 1_easy ├── 1_array │ ├── best_time_to_buy_and_sell_stock_ii │ │ ├── solution.go │ │ └── solution.py │ ├── contains_duplicate │ │ ├── solution.go │ │ └── solution.py │ ├── intersection_of_two_arrays_ii │ │ ├── solution.go │ │ └── solution.py │ ├── move_zeroes │ │ ├── solution.go │ │ └── solution.py │ ├── plus_one │ │ ├── solution.go │ │ └── solution.py │ ├── remove_duplicates_from_sorted_array │ │ ├── solution.go │ │ └── solution.py │ ├── rotate_array │ │ ├── solution.go │ │ └── solution.py │ ├── rotate_image │ │ ├── solution.go │ │ └── solution.py │ ├── single_number │ │ ├── solution.go │ │ └── solution.py │ ├── two_sum │ │ ├── solution.go │ │ └── solution.py │ └── valid_sudoku │ │ ├── solution.go │ │ └── solution.py ├── 2_strings │ ├── count_and_say │ │ ├── solution.go │ │ └── solution.py │ ├── first_unique_character_in_string │ │ ├── solution.go │ │ └── solution.py │ ├── implement_strStr │ │ ├── solution.go │ │ └── solution.py │ ├── longest_common_prefix │ │ ├── solution.go │ │ └── solution.py │ ├── reverse_integer │ │ ├── solution.go │ │ └── solution.py │ ├── reverse_string │ │ ├── solution.go │ │ └── solution.py │ ├── string_to_integer │ │ └── solution.py │ ├── valid_anagram │ │ ├── solution.go │ │ └── solution.py │ └── valid_palindrome │ │ ├── solution.go │ │ └── solution.py ├── 3_linked_list │ ├── delete_node_in_linked_list │ │ ├── solution.go │ │ └── solution.py │ ├── linked_list_cycle │ │ ├── solution.go │ │ └── solution.py │ ├── merge_two_sorted_lists │ │ ├── solution.go │ │ └── solution.py │ ├── palindrome_linked_list │ │ ├── solution.go │ │ └── solution.py │ ├── remove_nth_node_from_end_of_list │ │ ├── solution.go │ │ └── solution.py │ └── reverse_linked_list │ │ ├── solution.go │ │ └── solution.py ├── 4_trees │ ├── binary_tree_lever_order_traversal │ │ ├── solution.go │ │ └── solution.py │ ├── convert_sorted_array_to_BST │ │ ├── solution.go │ │ └── solution.py │ ├── maximum_depth_of_binary_tree │ │ ├── solution.go │ │ └── solution.py │ ├── symmetric_tree │ │ ├── solution.go │ │ └── solution.py │ └── validate_binary_search_tree │ │ ├── solution.go │ │ └── solution.py ├── 5_sorting_and_searching │ ├── first_bad_version │ │ └── solution.py │ └── merge_sorted_array │ │ └── solution.py ├── 6_dynamic_programming │ ├── best_time_to_buy_and_sell_stock │ │ ├── solution.go │ │ └── solution.py │ ├── climbing_stairs │ │ ├── solution.go │ │ └── solution.py │ ├── house_robber │ │ ├── solution.go │ │ └── solution.py │ └── maximum_subarray │ │ ├── solution.go │ │ └── solution.py ├── 7_design │ ├── min_stack │ │ ├── solution.go │ │ └── solution.py │ └── shuffle_an_array │ │ ├── solution.go │ │ └── solution.py ├── 8_math │ ├── count_primes │ │ ├── solution.go │ │ └── solution.py │ ├── fizz_buzz │ │ ├── solution.go │ │ └── solution.py │ ├── power_of_tree │ │ ├── solution.go │ │ └── solution.py │ └── roman_to_integer │ │ ├── solution.go │ │ └── solution.py └── 9_others │ ├── hamming_distance │ ├── solution.go │ └── solution.py │ ├── missing_number │ ├── solution.go │ └── solution.py │ ├── number_of_1_bits │ ├── solution.go │ └── solution.py │ ├── pascals_triangle │ ├── solution.go │ └── solution.py │ ├── reverse_bits │ ├── solution.go │ └── solution.py │ └── valid_parentheses │ ├── solution.go │ └── solution.py └── 2_medium ├── 1_array_and_strings ├── 3sum │ └── solution.py ├── group_anagrams │ ├── solution.go │ └── solution.py ├── increasing_triplet_subsequence │ ├── solution.go │ └── solution.py ├── longest_palindromic_substring │ ├── solution.go │ └── solution.py ├── longest_substr_without_repeating_chars │ ├── solution.go │ └── solution.py └── set_matrix_zeroes │ ├── solution.go │ └── solution.py ├── 2_linked_list ├── add_two_numbers │ ├── solution.go │ └── solution.py ├── intersection_of_two_linked_lists │ ├── solution.go │ └── solution.py └── odd_even_linked_list │ ├── solution.go │ └── solution.py ├── 3_trees_and_graphs ├── binary_tree_inorder_traversal │ ├── solution.go │ └── solution.py ├── binary_tree_zigzag_level_order_traversal │ └── solution.py ├── construct_binary_tree_from_preorder_and_inorder_traversal │ └── solution.py ├── kth_smallest_element_in_a_bst │ └── solution.py ├── number_of_islands │ └── solution.py └── populating_next_right_pointers_in_each_node │ └── solution.py ├── 4_backtracking ├── generate_parentheses │ └── solution.py ├── letter_combinations_of_phone_number │ └── solution.py ├── permutations │ └── solution.py ├── subsets │ └── solution.py └── word_search │ └── solution.py ├── 5_sorting_and_searching ├── find_peak_element │ ├── solution.go │ └── solution.py ├── kth_largest_element_in_an_array │ ├── solution.go │ └── solution.py ├── merge_intervals │ ├── solution.go │ └── solution.py ├── search_a_2d_matrix_ii │ └── solution.py ├── search_for_a_range │ └── solution.py ├── search_in_rotated_sorted_array │ └── solution.py ├── sort_colors │ └── solution.py └── top_k_frequent_elements │ └── solution.py ├── 6_dynamic_programming ├── coin_change │ └── solution.py ├── jump_game │ └── solution.py ├── longest_increasing_subsequence │ └── solution.py └── unique_paths │ └── solution.py ├── 7_design ├── insert_delete_get_random_O(1) │ ├── solution.go │ └── solution.py └── serialize_deserialize_binary_tree │ └── solution.py ├── 8_math ├── divide_two_integers │ └── solution.py ├── excel_sheet_column_number │ └── solution.py ├── factorial_trailing_zeroes │ └── solution.py ├── fraction_to_recurring_decimal │ └── solution.py ├── happy_number │ └── solution.py ├── power_of_x_to_n │ └── solution.py └── square_root_of_x │ └── solution.py └── 9_others ├── evaluate_reverse_polish_notation ├── solution.go └── solution.py ├── majority_element ├── solution.go └── solution.py ├── sum_of_two_integers └── solution.py └── task_scheduler └── solution.py /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | .vscode 3 | .idea 4 | -------------------------------------------------------------------------------- /30_day_challenge/01_single_number.py: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/problems/single-number/submissions/ 2 | 3 | class Solution: 4 | def singleNumber(self, numbers: List[int]) -> int: 5 | xor_sum = 0 6 | 7 | for number in numbers: 8 | xor_sum = xor_sum ^ number 9 | 10 | return xor_sum 11 | -------------------------------------------------------------------------------- /30_day_challenge/02_happy_number.py: -------------------------------------------------------------------------------- 1 | def pdi_function(number, base: int = 10): 2 | """Perfect digital invariant function.""" 3 | total = 0 4 | while number > 0: 5 | total = total + pow(number % base, 2) 6 | number = number // base 7 | return total 8 | 9 | def is_happy(number: int) -> bool: 10 | """Determine if the specified number is a happy number.""" 11 | seen_numbers = [] 12 | while number > 1 and number not in seen_numbers: 13 | seen_numbers.append(number) 14 | number = pdi_function(number) 15 | return number == 1 16 | 17 | class Solution: 18 | def isHappy(self, n: int) -> bool: 19 | return is_happy(n) 20 | -------------------------------------------------------------------------------- /30_day_challenge/03_max_sub_array.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxSubArray(self, nums: List[int]) -> int: 3 | n = len(nums) 4 | if n == 1: 5 | return nums[0] 6 | 7 | max_sum = curr_sum = nums[0] 8 | 9 | for num in nums[1:]: 10 | curr_sum = max(curr_sum + num, num) 11 | 12 | if curr_sum > max_sum: 13 | max_sum = curr_sum 14 | 15 | return max_sum 16 | -------------------------------------------------------------------------------- /30_day_challenge/04_move_zeros.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def moveZeroes(self, nums: List[int]) -> None: 3 | number_of_zeros = 0 4 | 5 | # todo: use 2 pointers 6 | for index in range(len(nums)-1, -1, -1): 7 | if nums[index] == 0: 8 | del nums[index] 9 | nums.append(0) 10 | -------------------------------------------------------------------------------- /30_day_challenge/05_max_profit.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxProfit(self, prices: List[int]) -> int: 3 | if not prices: 4 | return 0 5 | 6 | max_val = min_val = prices[0] 7 | total_gain = current_gain = 0 8 | 9 | for index in range(1, len(prices)): 10 | if prices[index] < max_val: 11 | current_gain = max_val - min_val 12 | total_gain += current_gain 13 | min_val = prices[index] 14 | 15 | max_val = prices[index] 16 | 17 | 18 | current_gain = max_val - min_val 19 | total_gain += current_gain 20 | 21 | return total_gain 22 | -------------------------------------------------------------------------------- /30_day_challenge/06_group_anagram.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Solution: 4 | def groupAnagrams(self, strs: List[str]) -> List[List[str]]: 5 | groups = collections.defaultdict(list) 6 | 7 | for s in strs: 8 | key = tuple(sorted(s)) 9 | groups[key].append(s) 10 | 11 | return groups.values() 12 | -------------------------------------------------------------------------------- /30_day_challenge/07_count_elements.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def countElements(self, arr: List[int]) -> int: 3 | nums = set(arr) 4 | count = 0 5 | for num in arr: 6 | if num+1 in nums: 7 | count += 1 8 | 9 | return count 10 | -------------------------------------------------------------------------------- /30_day_challenge/08_middle_node.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def middleNode(self, head: ListNode) -> ListNode: 3 | slow = head 4 | fast = head 5 | 6 | while fast != None and fast.next != None: 7 | slow = slow.next 8 | fast = fast.next.next 9 | 10 | return slow 11 | -------------------------------------------------------------------------------- /30_day_challenge/09_backspace_compare.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def backspaceCompare(self, S: str, T: str) -> bool: 3 | stack_s = self.process(S) 4 | stack_t = self.process(T) 5 | 6 | return stack_t == stack_s 7 | 8 | def process(self, keys): 9 | stack = [] 10 | for key in keys: 11 | if key == '#': 12 | if len(stack) > 0: 13 | stack.pop() 14 | continue 15 | 16 | stack.append(key) 17 | 18 | return stack 19 | -------------------------------------------------------------------------------- /30_day_challenge/10_min_stack.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, value, min_value): 3 | self.value = value 4 | self.min_value = min_value 5 | 6 | 7 | class MinStack: 8 | 9 | def __init__(self): 10 | """ 11 | initialize your data structure here. 12 | """ 13 | self.stack = [] 14 | 15 | def push(self, value: int) -> None: 16 | min_value = value 17 | if len(self.stack) > 0: 18 | prev_min_value = self.stack[-1].min_value 19 | min_value = min(prev_min_value, min_value) 20 | 21 | node = Node(value, min_value) 22 | self.stack.append(node) 23 | 24 | def pop(self) -> None: 25 | self.stack.pop() 26 | 27 | def top(self) -> int: 28 | return self.stack[-1].value 29 | 30 | def getMin(self) -> int: 31 | return self.stack[-1].min_value 32 | -------------------------------------------------------------------------------- /30_day_challenge/11_diameter_of_binary_tree.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | class TreeNode: 3 | def __init__(self, x): 4 | self.val = x 5 | self.left = None 6 | self.right = None 7 | 8 | class Solution: 9 | def diameterOfBinaryTree(self, root: TreeNode) -> int: 10 | if not root: 11 | return 0 12 | 13 | return self.helper(root) - 1 14 | 15 | def helper(self, root: TreeNode) -> int: 16 | if not root: 17 | return 0 18 | 19 | l_height = self.height(root.left) 20 | r_height = self.height(root.right) 21 | 22 | l_diameter = self.helper(root.left) 23 | r_diameter = self.helper(root.right) 24 | 25 | return max(l_height+r_height+1, max(l_diameter, r_diameter)) 26 | 27 | def height(self, tree): 28 | if not tree: 29 | return 0 30 | 31 | return 1 + max(self.height(tree.left), self.height(tree.right)) 32 | -------------------------------------------------------------------------------- /30_day_challenge/12_last_stone_weight.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | from typing import List 3 | 4 | 5 | class MaxHeap: 6 | def __init__(self): 7 | self.data = [] 8 | 9 | def top(self): 10 | return -self.data[0] 11 | 12 | def push(self, val): 13 | heapq.heappush(self.data, -val) 14 | 15 | def pop(self): 16 | return -heapq.heappop(self.data) 17 | 18 | 19 | class Solution: 20 | def lastStoneWeight(self, stones: List[int]) -> int: 21 | diff = 0 22 | heap = MaxHeap() 23 | 24 | for s in stones: 25 | heap.push(s) 26 | 27 | while True: 28 | try: 29 | one = heap.pop() 30 | except IndexError: 31 | return diff 32 | 33 | try: 34 | two = heap.pop() 35 | except IndexError: 36 | return one 37 | 38 | diff = one - two 39 | if diff != 0: 40 | heap.push(diff) 41 | 42 | return diff 43 | -------------------------------------------------------------------------------- /30_day_challenge/13_contigious_array.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def findMaxLength(self, nums: List[int]) -> int: 3 | max_contiguous = 0 4 | first_occurances = {0: -1} 5 | sum_ = 0 6 | 7 | for i, num in enumerate(nums): 8 | if num == 0: 9 | sum_ -= 1 10 | else: 11 | sum_ += 1 12 | 13 | if sum_ not in first_occurances: 14 | first_occurances[sum_] = i 15 | continue 16 | 17 | max_contiguous = max(i - first_occurances[sum_], max_contiguous) 18 | 19 | return max_contiguous 20 | -------------------------------------------------------------------------------- /30_day_challenge/14_string_shift.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def stringShift(self, string: str, shifts: List[List[int]]) -> str: 3 | shift_sum = 0 4 | for shift in shifts: 5 | if shift[0] == 0: 6 | shift_sum += shift[1] 7 | else: 8 | shift_sum -= shift[1] 9 | 10 | shift_sum = shift_sum % len(string) 11 | 12 | return string[shift_sum:] + string[:shift_sum] 13 | -------------------------------------------------------------------------------- /30_day_challenge/15_product_except_self.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def productExceptSelf(self, nums: List[int]) -> List[int]: 3 | zeros = nums.count(0) 4 | if zeros > 1: 5 | return [0 for _ in nums] 6 | 7 | product = 1 8 | for n in nums: 9 | if n != 0: 10 | product = product * n 11 | 12 | if zeros == 1: 13 | return [0 if n != 0 else product for n in nums] 14 | 15 | for i, n in enumerate(nums): 16 | nums[i] = int(product / n) 17 | 18 | return nums 19 | -------------------------------------------------------------------------------- /30_day_challenge/16_valid_parenthesis.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def checkValidString(self, s: str) -> bool: 3 | if not self.checkValid(s, '('): 4 | return False 5 | 6 | if not self.checkValid(reversed(s), ')'): 7 | return False 8 | 9 | return True 10 | 11 | def checkValid(self, s, open_parenthesis): 12 | balance = 0 13 | for char in s: 14 | if char in [open_parenthesis, '*']: 15 | balance += 1 16 | else: 17 | balance -= 1 18 | 19 | if balance == -1: 20 | return False 21 | return True 22 | -------------------------------------------------------------------------------- /30_day_challenge/17_number_of_islands.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | neighbours = [[-1, 0], [0, -1], [1, 0], [0, 1]] 3 | 4 | def numIslands(self, grid): 5 | if not grid or not grid[0]: 6 | return 0 7 | 8 | count = 0 9 | visited = [[False for row in column] for column in grid] 10 | rows = len(grid) 11 | cols = len(grid[0]) 12 | 13 | for i in range(rows): 14 | for j in range(cols): 15 | if not visited[i][j] and grid[i][j] == '1': 16 | self.dfs(grid, i, j, visited) 17 | count += 1 18 | 19 | return count 20 | 21 | def dfs(self, grid, i, j, visited): 22 | if not self.in_border(grid, i, j) or visited[i][j] or grid[i][j] == '0': 23 | return 24 | 25 | visited[i][j] = True 26 | for neighbour in self.neighbours: 27 | self.dfs(grid, i + neighbour[0], j + neighbour[1], visited) 28 | 29 | def in_border(self, grid, i, j): 30 | if i < 0 or j < 0: 31 | return False 32 | 33 | if i >= len(grid) or j >= len(grid[0]): 34 | return False 35 | 36 | return True 37 | -------------------------------------------------------------------------------- /30_day_challenge/18_min_path_sum.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def minPathSum(self, grid: List[List[int]]) -> int: 3 | rows, cols = len(grid), len(grid[0]) 4 | dp = [[0 for _ in range(cols)] for _ in range(rows)] 5 | dp[0][0] = grid[0][0] 6 | 7 | for i in range(1, rows): 8 | dp[i][0] = dp[i-1][0] + grid[i][0] 9 | 10 | for j in range(1, cols): 11 | dp[0][j] = dp[0][j-1] + grid[0][j] 12 | 13 | for i in range(1, rows): 14 | for j in range(1, cols): 15 | dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j] 16 | 17 | return dp[rows-1][cols-1] 18 | -------------------------------------------------------------------------------- /30_day_challenge/20_contruct_bst_from_preorder.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | class TreeNode: 3 | def __init__(self, val=0, left=None, right=None): 4 | self.val = val 5 | self.left = left 6 | self.right = right 7 | 8 | class Solution: 9 | def bstFromPreorder(self, preorder: List[int]) -> TreeNode: 10 | if not preorder: 11 | return None 12 | 13 | val = preorder[0] 14 | root = TreeNode(val) 15 | root.left = self.bstFromPreorder([n for n in preorder if n < val]) 16 | root.right = self.bstFromPreorder([n for n in preorder if n > val]) 17 | 18 | return root 19 | -------------------------------------------------------------------------------- /30_day_challenge/21_left_most_column.py: -------------------------------------------------------------------------------- 1 | # """ 2 | # This is BinaryMatrix's API interface. 3 | # You should not implement it, or speculate about its implementation 4 | # """ 5 | #class BinaryMatrix(object): 6 | # def get(self, row: int, col: int) -> int: 7 | # def dimensions(self) -> list[]: 8 | 9 | class Solution: 10 | def leftMostColumnWithOne(self, binaryMatrix: 'BinaryMatrix') -> int: 11 | self.binaryMatrix = binaryMatrix 12 | self.rows, self.cols = binaryMatrix.dimensions() 13 | 14 | if any(self.getColumnValue(0)): 15 | return 0 16 | 17 | high, low = self.rows - 1, 0 18 | while low <= high: 19 | middle = (low + high + 1) // 2 20 | 21 | if any(self.getColumnValue(middle)): 22 | high = middle - 1 23 | else: 24 | low = middle + 1 25 | 26 | if low < self.cols and any(self.getColumnValue(low)): 27 | return low 28 | 29 | return -1 30 | 31 | def getColumnValue(self, index): 32 | return tuple(self.binaryMatrix.get(i, index) for i in range(self.rows)) 33 | -------------------------------------------------------------------------------- /30_day_challenge/22_sub_array_sum_equals_k.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def subarraySum(self, nums: List[int], k: int) -> int: 3 | length = len(nums) 4 | sum_ = 0 5 | dict_ = {0: 1} 6 | count = 0 7 | 8 | for n in nums: 9 | sum_ += n 10 | if (sum_ - k) in dict_: 11 | count += dict_[sum_ - k] 12 | 13 | dict_[sum_] = dict_.get(sum_, 0) + 1 14 | 15 | return count 16 | 17 | -------------------------------------------------------------------------------- /30_day_challenge/23_bitwise_range_and.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def rangeBitwiseAnd(self, m: int, n: int) -> int: 3 | m, n = bin(m)[2:], bin(n)[2:] 4 | 5 | if len(m) != len(n): 6 | return 0 7 | 8 | result = "" 9 | for i, j in zip(m, n): 10 | if i != j: 11 | break 12 | 13 | result += str(i) 14 | 15 | result += "0" * (len(m) - len(result)) 16 | 17 | return int(result, 2) 18 | -------------------------------------------------------------------------------- /30_day_challenge/24_lru_cache.py: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/problems/lru-cache/ 2 | from collections import OrderedDict 3 | 4 | class LRUCache: 5 | def __init__(self, capacity: int): 6 | self.capacity = capacity 7 | self.cache = OrderedDict() 8 | 9 | def get(self, key: int) -> int: 10 | if key not in self.cache: 11 | return -1 12 | 13 | value = self.cache[key] 14 | del self.cache[key] 15 | self.cache[key] = value 16 | 17 | return value 18 | 19 | def put(self, key: int, value: int) -> None: 20 | if key not in self.cache and len(self.cache) >= self.capacity: 21 | least_used = next(iter(self.cache.keys())) 22 | 23 | del self.cache[least_used] 24 | 25 | if key in self.cache: 26 | del self.cache[key] 27 | 28 | self.cache[key] = value 29 | 30 | 31 | def delete_least_recent(self): 32 | next(iter(d.items())) 33 | 34 | # Your LRUCache object will be instantiated and called as such: 35 | # obj = LRUCache(capacity) 36 | # param_1 = obj.get(key) 37 | # obj.put(key,value) -------------------------------------------------------------------------------- /30_day_challenge/25_jump_game.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def canJump(self, nums: List[int]) -> bool: 3 | if len(nums) == 1: 4 | return True 5 | 6 | if nums[0] == 0: 7 | return False 8 | 9 | jumps = nums[0] 10 | 11 | for num in nums[1:-1]: 12 | jumps = max(num, jumps - 1) 13 | if jumps <= 0: 14 | return False 15 | 16 | return True 17 | -------------------------------------------------------------------------------- /30_day_challenge/27_max_square.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maximalSquare(self, matrix: List[List[str]]) -> int: 3 | if not matrix or not matrix[0]: 4 | return 0 5 | 6 | max_square = 0 7 | cols, rows = len(matrix), len(matrix[0]) 8 | dp = [[0 for _ in range(rows)] for _ in range(cols)] 9 | 10 | for i in range(cols): 11 | dp[i][0] = int(matrix[i][0]) 12 | max_square = max(max_square, dp[i][0]) 13 | 14 | for j in range(rows): 15 | dp[0][j] = int(matrix[0][j]) 16 | max_square = max(max_square, dp[0][j]) 17 | 18 | for i in range(1, cols): 19 | for j in range(1, rows): 20 | val = int(matrix[i][j]) 21 | if val != 0: 22 | dp[i][j] = min(int(dp[i-1][j]), int(dp[i][j-1]), int(dp[i-1][j-1])) + val 23 | max_square = max(max_square, dp[i][j]) 24 | 25 | return max_square * max_square 26 | -------------------------------------------------------------------------------- /30_day_challenge/28_first_unique_num.py: -------------------------------------------------------------------------------- 1 | class FirstUnique: 2 | def __init__(self, nums: List[int]): 3 | self.counter = collections.Counter(nums) 4 | self.unique = {n: True for n in self.counter if self.counter[n] == 1} 5 | 6 | def showFirstUnique(self) -> int: 7 | try: 8 | return next(iter(self.unique)) 9 | except StopIteration: 10 | return -1 11 | 12 | def add(self, value: int) -> None: 13 | if self.counter[value] == 0: 14 | self.unique[value] = True 15 | 16 | if self.counter[value] == 1: 17 | del self.unique[value] 18 | 19 | self.counter[value] += 1 20 | -------------------------------------------------------------------------------- /30_day_challenge/30_is_valid_sequence.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isValidSequence(self, root: TreeNode, arr: List[int]) -> bool: 3 | if not root and not arr: 4 | return False 5 | 6 | if not arr: 7 | return not bool(root) 8 | 9 | if not root: 10 | return False 11 | 12 | if root.val != arr[0]: 13 | return False 14 | 15 | is_leaf = not root.left and not root.right 16 | if is_leaf: 17 | return len(arr) == 1 18 | 19 | left_valid = self.isValidSequence(root.left, arr[1:]) 20 | right_valid = self.isValidSequence(root.right, arr[1:]) 21 | 22 | return left_valid or right_valid 23 | -------------------------------------------------------------------------------- /algorithms/add_strings.py: -------------------------------------------------------------------------------- 1 | from itertools import zip_longest 2 | 3 | class Solution: 4 | def addStrings(num1, num2): 5 | carry = 0 6 | result = "" 7 | num1, num2 = reversed(num1), reversed(num2) 8 | 9 | for c1, c2 in zip_longest(num1, num2, fillvalue="0"): 10 | d1, d2 = int(c1), int(c2) 11 | sum_ = d1 + d2 + carry 12 | carry = sum_ // 10 13 | result = str(sum_ % 10) + result 14 | 15 | if carry: 16 | result = str(carry) + result 17 | 18 | return result 19 | -------------------------------------------------------------------------------- /algorithms/backspace_string_compare.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def backspaceCompare(self, S: str, T: str) -> bool: 3 | stack_s = self.process(S) 4 | stack_t = self.process(T) 5 | 6 | return stack_t == stack_s 7 | 8 | def process(self, keys): 9 | stack = [] 10 | for key in keys: 11 | if key == '#': 12 | if len(stack) > 0: 13 | stack.pop() 14 | continue 15 | 16 | stack.append(key) 17 | 18 | return stack 19 | -------------------------------------------------------------------------------- /algorithms/base_7.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def convertToBase7(self, num: int) -> str: 3 | if num == 0: 4 | return "0" 5 | 6 | remainders = [] 7 | is_negative = num < 0 8 | num = abs(num) 9 | 10 | while num: 11 | remainder = num % 7 12 | num = num // 7 13 | remainders.append(str(remainder)) 14 | 15 | remainders = reversed(remainders) 16 | 17 | result = "".join(remainders) 18 | if is_negative: 19 | result = "-" + result 20 | 21 | return result 22 | 23 | 24 | if __name__ == '__main__': 25 | s = Solution() 26 | cases = [ 27 | (100, "202"), 28 | (-7, "-10"), 29 | ] 30 | 31 | for case in cases: 32 | print("PASS" if s.convertToBase7(case[0]) == case[1] else "FAIL") 33 | -------------------------------------------------------------------------------- /algorithms/binary_gap.py: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/problems/binary-gap/ 2 | 3 | 4 | class Solution: 5 | def binaryGap(self, N: int) -> int: 6 | s = bin(N).strip('0b') 7 | 8 | if s.count('1') < 2: 9 | return 0 10 | 11 | return len(max(s.split('1'), key=len)) + 1 12 | -------------------------------------------------------------------------------- /algorithms/binary_tree_height.py: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/problems/maximum-depth-of-binary-tree/ 2 | 3 | class TreeNode: 4 | def __init__(self, x): 5 | self.val = x 6 | self.left = None 7 | self.right = None 8 | 9 | def maxDepth(root): 10 | if not root: 11 | return 0 12 | 13 | return max(maxDepth(root.left), maxDepth(root.right)) + 1 14 | 15 | if __name__ == '__main__': 16 | root = TreeNode(3) 17 | root.left = TreeNode(9) 18 | root.right = TreeNode(20) 19 | root.right.left = TreeNode(15) 20 | root.right.right = TreeNode(7) 21 | 22 | print("PASS" if maxDepth(root) == 3 else "FAIL") 23 | -------------------------------------------------------------------------------- /algorithms/binary_tree_paths.py: -------------------------------------------------------------------------------- 1 | 2 | # https://leetcode.com/problems/binary-tree-paths/ 3 | class Solution: 4 | def binaryTreePaths(self, root: TreeNode) -> List[str]: 5 | self.result = [] 6 | self.helper(root, "") 7 | return self.result 8 | def helper(self, root: TreeNode, prev_path: str) -> List[str]: 9 | if not root: 10 | return 11 | path = f"{prev_path}->{root.val}" if prev_path else f"{root.val}" 12 | if not root.left and not root.right: 13 | self.result.append(path) 14 | self.helper(root.left, path) 15 | self.helper(root.right, path) 16 | -------------------------------------------------------------------------------- /algorithms/bitwise_and_sum.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def rangeBitwiseAnd(self, m: int, n: int) -> int: 3 | m, n = bin(m)[2:], bin(n)[2:] 4 | 5 | if len(m) != len(n): 6 | return 0 7 | 8 | result = "" 9 | for i, j in zip(m, n): 10 | if i != j: 11 | break 12 | 13 | result += str(i) 14 | 15 | result += "0" * (len(m) - len(result)) 16 | 17 | return int(result, 2) 18 | -------------------------------------------------------------------------------- /algorithms/bitwise_complement.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def bitwiseComplement(self, N: int) -> int: 3 | binary = bin(N)[2:] 4 | binary = binary.replace("0", "T") 5 | binary = binary.replace("1", "0") 6 | binary = binary.replace("T", "1") 7 | 8 | return int(binary, 2) 9 | -------------------------------------------------------------------------------- /algorithms/break_integer.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def integerBreak(self, n: int) -> int: 3 | if n == 0: 4 | return 0 5 | 6 | size = n if n > 6 else 6 7 | dp = [None for _ in range(size)] 8 | dp[0], dp[1], dp[2] = 0, 1, 2 9 | dp[3], dp[4], dp[5] = 4, 6, 9 10 | 11 | for i in range(6, n): 12 | dp[i] = max(dp[i-2] * 2, dp[i-3] * 3, dp[i-5] * 5) 13 | 14 | return dp[n-1] 15 | -------------------------------------------------------------------------------- /algorithms/clone_graph.py: -------------------------------------------------------------------------------- 1 | # Definition for a Node. 2 | class Node: 3 | def __init__(self, val = 0, neighbors = None): 4 | self.val = val 5 | self.neighbors = neighbors if neighbors is not None else [] 6 | 7 | 8 | class Solution: 9 | def cloneGraph(self, node: 'Node') -> 'Node': 10 | if not node: return None 11 | visited, copy_map = set(), {} 12 | queue = collections.deque() 13 | 14 | copy_node_root = Node(node.val) 15 | copy_map[node] = copy_node_root 16 | queue.appendleft((copy_node_root, node)) 17 | 18 | while len(queue) != 0: 19 | copy_node, node = queue.pop() 20 | if node in visited: 21 | continue 22 | 23 | for neighbor in node.neighbors: 24 | if neighbor in copy_map: 25 | copy_neighbor = copy_map[neighbor] 26 | else: 27 | copy_neighbor = Node(neighbor.val) 28 | copy_map[neighbor] = copy_neighbor 29 | copy_node.neighbors.append(copy_neighbor) 30 | queue.appendleft((copy_neighbor, neighbor)) 31 | 32 | visited.add(node) 33 | 34 | return copy_node_root 35 | -------------------------------------------------------------------------------- /algorithms/compare_version_numbers.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def compareVersion(self, version1: str, version2: str) -> int: 3 | version1 = list(map(int, version1.split("."))) 4 | version2 = list(map(int, version2.split("."))) 5 | version1_size = len(version1) 6 | version2_size = len(version2) 7 | 8 | maxlen = max([version1_size, version2_size]) 9 | if version1_size < maxlen: 10 | version1.extend([0]*(maxlen-version1_size)) 11 | 12 | if version2_size < maxlen: 13 | version2.extend([0]*(maxlen-version2_size)) 14 | 15 | if tuple(version1) == tuple(version2): 16 | return 0 17 | elif tuple(version1) > tuple(version2): 18 | return 1 19 | else: 20 | return -1 21 | -------------------------------------------------------------------------------- /algorithms/convert_to_hex.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def toHex(self, num: int) -> str: 3 | if num >= 0: 4 | return hex(num)[2:] 5 | 6 | return hex(2**32+num)[2:] 7 | -------------------------------------------------------------------------------- /algorithms/delete_duplicates_from_sorted_list.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 | class Solution: 8 | def deleteDuplicates(self, head): 9 | if not head: 10 | return None 11 | 12 | current = head 13 | prev = current 14 | current = current.next 15 | 16 | while current: 17 | if current.val == prev.val: 18 | if current.next: 19 | current.val = current.next.val 20 | current.next = current.next.next 21 | else: 22 | prev.next = None 23 | 24 | prev = current 25 | current = current.next 26 | 27 | return head 28 | 29 | head = ListNode(1) 30 | head.next = ListNode(1) 31 | head.next.next = ListNode(1) 32 | 33 | l = Solution().deleteDuplicates(head) 34 | while l: 35 | print(l.val) 36 | l = l.next 37 | -------------------------------------------------------------------------------- /algorithms/diagonal_traverse.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def findDiagonalOrder(self, matrix: List[List[int]]) -> List[int]: 6 | m, n = len(matrix), len(matrix[0]) 7 | result = [] 8 | flip = False 9 | 10 | for i in range(m-1): 11 | x, y = i, 0 12 | row = [] 13 | while m > x >= 0 and n > y >= 0: 14 | row.append(matrix[x][y]) 15 | x -= 1 16 | y += 1 17 | 18 | if flip: 19 | row = row[::-1] 20 | 21 | result.extend(row) 22 | flip = not flip 23 | 24 | for idx, i in enumerate(range(m, m + n)): 25 | x, y = m - 1, idx 26 | row = [] 27 | while m > x >= 0 and n > y >= 0: 28 | row.append(matrix[x][y]) 29 | x -= 1 30 | y += 1 31 | 32 | if flip: 33 | row = row[::-1] 34 | 35 | result.extend(row) 36 | flip = not flip 37 | 38 | return result 39 | 40 | 41 | if __name__ == '__main__': 42 | arr = [ 43 | [1, 2, 3], 44 | [4, 5, 6], 45 | [7, 8, 9] 46 | ] 47 | s = Solution() 48 | print(s.findDiagonalOrder(arr)) 49 | -------------------------------------------------------------------------------- /algorithms/diameter_of_tree.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | class TreeNode: 3 | def __init__(self, x): 4 | self.val = x 5 | self.left = None 6 | self.right = None 7 | 8 | class Solution: 9 | def diameterOfBinaryTree(self, root: TreeNode) -> int: 10 | if not root: 11 | return 0 12 | 13 | l_height = self.height(root.left) 14 | r_height = self.height(root.right) 15 | 16 | l_diameter = self.diameterOfBinaryTree(root.left) 17 | r_diameter = self.diameterOfBinaryTree(root.right) 18 | 19 | return max(l_height+r_height+1, max(l_diameter, r_diameter)) - 1 20 | 21 | def height(self, tree): 22 | if not tree: 23 | return 0 24 | 25 | return 1 + max(self.height(tree.left), self.height(tree.right)) 26 | 27 | 28 | if __name__ == '__main__': 29 | s = Solution() 30 | root = TreeNode(1) 31 | root.left = TreeNode(2) 32 | root.right = TreeNode(3) 33 | root.left.left = TreeNode(4) 34 | root.left.right = TreeNode(5) 35 | 36 | print(s.diameterOfBinaryTree(root)) 37 | -------------------------------------------------------------------------------- /algorithms/excel_sheet_column_title.py: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/problems/excel-sheet-column-title/ 2 | 3 | class Solution: 4 | def __init__(self): 5 | self.letters = {} 6 | self.letters_count = 26 7 | self.fill_letters() 8 | 9 | def fill_letters(self): 10 | self.letters[0] = 'Z' 11 | for i in range(self.letters_count): 12 | self.letters[i + 1] = chr(65+i) 13 | 14 | def convertToTitle(self, n: int) -> str: 15 | result = [] 16 | 17 | while n > self.letters_count: 18 | rem = n % self.letters_count 19 | n = n // self.letters_count 20 | result.append(self.letters[rem]) 21 | if rem == 0: 22 | n -= 1 23 | 24 | result.append(self.letters[n]) 25 | 26 | return "".join(reversed(result)) 27 | -------------------------------------------------------------------------------- /algorithms/first_missing_positive_int.py: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/problems/first-missing-positive/ 2 | 3 | def min_positive_missing_int(numbers): 4 | numbers = [number for number in numbers if number > 0] 5 | if not numbers: 6 | return 1 7 | 8 | seen = set(numbers) 9 | min_num = min(numbers) 10 | 11 | if min_num > 1: 12 | return 1 13 | 14 | candidates = [] 15 | for number in numbers: 16 | if (number + 1) not in seen: 17 | candidates.append(number+1) 18 | 19 | return min(candidates) 20 | 21 | 22 | if __name__ == '__main__': 23 | cases = [ 24 | ([1, 3, 1, 4, 6, 2], 5), 25 | ([1, 2, 3], 4), 26 | ([-3, -5], 1), 27 | ([1, 4, 100], 2), 28 | ([1000, 10001, 2000], 1) 29 | ] 30 | 31 | for case in cases: 32 | print("PASS" if min_positive_missing_int(case[0]) == case[1] else "FAIL") 33 | 34 | -------------------------------------------------------------------------------- /algorithms/first_unique_number.py: -------------------------------------------------------------------------------- 1 | class FirstUnique: 2 | 3 | def __init__(self, nums: List[int]): 4 | self.counter = collections.Counter(nums) 5 | self.unique = {n: True for n in self.counter if self.counter[n] == 1} 6 | 7 | def showFirstUnique(self) -> int: 8 | try: 9 | return next(iter(self.unique)) 10 | except StopIteration: 11 | return -1 12 | 13 | def add(self, value: int) -> None: 14 | if self.counter[value] == 0: 15 | self.unique[value] = True 16 | 17 | if self.counter[value] == 1: 18 | del self.unique[value] 19 | 20 | self.counter[value] += 1 21 | -------------------------------------------------------------------------------- /algorithms/invert-binary-tree.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution: 9 | def invertTree(self, root: TreeNode) -> TreeNode: 10 | if not root: 11 | return 12 | 13 | inverted = TreeNode(root.val) 14 | if root.left: 15 | inverted.right = self.invertTree(root.left) 16 | 17 | if root.right: 18 | inverted.left = self.invertTree(root.right) 19 | 20 | return inverted 21 | -------------------------------------------------------------------------------- /algorithms/is_same_tree.py: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/submissions/detail/273110692/ 2 | # Definition for a binary tree node. 3 | class TreeNode: 4 | def __init__(self, x): 5 | self.val = x 6 | self.left = None 7 | self.right = None 8 | 9 | 10 | def is_same_tree(p: TreeNode, q: TreeNode) -> bool: 11 | if not p and not q: 12 | return True 13 | 14 | if not p or not q: 15 | return False 16 | 17 | return p.val == q.val and is_same_tree(p.left, q.left) and is_same_tree(p.right, q.right) 18 | 19 | if __name__ == '__main__': 20 | t1 = TreeNode(1) 21 | t1.left = TreeNode(2) 22 | t1.right = TreeNode(3) 23 | 24 | t2 = TreeNode(1) 25 | t2.left = TreeNode(2) 26 | t2.right = TreeNode(4) 27 | 28 | print("PASS" if is_same_tree(t1, t1) is True else "FAIL") 29 | print("PASS" if is_same_tree(t2, t1) is False else "FAIL") 30 | -------------------------------------------------------------------------------- /algorithms/is_valid_sequence.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, val=0, left=None, right=None): 4 | # self.val = val 5 | # self.left = left 6 | # self.right = right 7 | 8 | class Solution: 9 | def isValidSequence(self, root: TreeNode, arr: List[int], is_leaf=False) -> bool: 10 | if not root and not arr: 11 | return is_leaf 12 | 13 | if not arr: 14 | return not bool(root) 15 | 16 | if not root: 17 | return False 18 | 19 | if root.val != arr[0]: 20 | return False 21 | 22 | is_leaf = not root.left and not root.right 23 | left_valid = self.isValidSequence(root.left, arr[1:], is_leaf) 24 | right_valid = self.isValidSequence(root.right, arr[1:], is_leaf) 25 | 26 | return left_valid or right_valid 27 | -------------------------------------------------------------------------------- /algorithms/k_closest_points_to_origin.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | 3 | 4 | class Solution: 5 | def kClosest(self, points: List[List[int]], K: int) -> List[List[int]]: 6 | def distance_squared(point): 7 | return point[0] ** 2 + point[1] ** 2 8 | 9 | return heapq.nsmallest(K, points, key=distance_squared) 10 | -------------------------------------------------------------------------------- /algorithms/k_diff_pairs_in_an_array.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def findPairs(self, nums: List[int], k: int) -> int: 3 | nums_counter = collections.Counter(nums) 4 | result = 0 5 | 6 | for num in nums_counter: 7 | if k < 0: 8 | continue 9 | 10 | if k == 0: 11 | if nums_counter[num] > 1: 12 | result += 1 13 | continue 14 | 15 | if (num + k) in nums_counter: 16 | result += 1 17 | 18 | return result 19 | -------------------------------------------------------------------------------- /algorithms/longest_absolute_file_path.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def lengthLongestPath(self, input: str) -> int: 3 | levels = {} 4 | max_path_len = 0 5 | entries = input.split("\n") 6 | 7 | for entry in entries: 8 | tabs = entry.count("\t") 9 | current_path_len = len(entry) - tabs 10 | 11 | if tabs > 0: 12 | current_path_len += levels[tabs-1] + 1 13 | 14 | if "." in entry: 15 | max_path_len = max(max_path_len, current_path_len) 16 | else: 17 | levels[tabs] = current_path_len 18 | 19 | return max_path_len 20 | 21 | 22 | if __name__ == "__main__": 23 | s = Solution() 24 | print(s.lengthLongestPath(""" 25 | dir 26 | \tsubdir1 27 | \t\tfile1.ext 28 | \t\tsubsubdir1 29 | \tsubdir2 30 | \t\tsubsubdir2 31 | \t\t\tfile2.ext 32 | """)) 33 | print(len("dir/subdir2/subsubdir2/file2.ext")) 34 | -------------------------------------------------------------------------------- /algorithms/lru_cache.py: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/problems/lru-cache/ 2 | from collections import OrderedDict 3 | 4 | class LRUCache: 5 | def __init__(self, capacity: int): 6 | self.capacity = capacity 7 | self.cache = OrderedDict() 8 | 9 | def get(self, key: int) -> int: 10 | if key not in self.cache: 11 | return -1 12 | 13 | value = self.cache[key] 14 | del self.cache[key] 15 | self.cache[key] = value 16 | 17 | return value 18 | 19 | def put(self, key: int, value: int) -> None: 20 | if key not in self.cache and len(self.cache) >= self.capacity: 21 | least_used = next(iter(self.cache.keys())) 22 | 23 | del self.cache[least_used] 24 | 25 | if key in self.cache: 26 | del self.cache[key] 27 | 28 | self.cache[key] = value 29 | -------------------------------------------------------------------------------- /algorithms/math_sqrt.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def mySqrt(self, a: int) -> int: 3 | if a == 0: 4 | return 0 5 | 6 | x = a 7 | for _ in range(25): 8 | x = 0.5 * (x + a / x) 9 | 10 | return int(x) 11 | -------------------------------------------------------------------------------- /algorithms/max_product_of_tree_nums.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maximumProduct(self, nums: List[int]) -> int: 3 | # no need to sort with nlogn. 4 | # instead use heap to find 3 max and 3 min nums. 5 | nums.sort() 6 | 7 | if nums[0] <= nums[1] < 0: 8 | negative = nums[0] * nums[1] * nums[-1] 9 | positive = nums[-1] * nums[-2] * nums[-3] 10 | 11 | return max(negative, positive) 12 | 13 | return nums[-1] * nums[-2] * nums[-3] 14 | -------------------------------------------------------------------------------- /algorithms/max_product_of_word_lengths.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | word_mask = {} 3 | 4 | def maxProduct(self, words: List[str]) -> int: 5 | self.word_mask = {word: self.mask(word) for word in words} 6 | global_max = 0 7 | 8 | for word_one, mask_one in self.word_mask.items(): 9 | for word_two, mask_two in self.word_mask.items(): 10 | if self.isValid(mask_one, mask_two): 11 | global_max = max(global_max, len(word_one) * len(word_two)) 12 | 13 | return global_max 14 | 15 | def isValid(self, mask_one, mask_two): 16 | return mask_one & mask_two == 0 17 | 18 | def mask(word: str) -> int: 19 | return 20 | -------------------------------------------------------------------------------- /algorithms/maximum_depth_of_tree.py: -------------------------------------------------------------------------------- 1 | """ 2 | # Definition for a Node. 3 | class Node: 4 | def __init__(self, val=None, children=None): 5 | self.val = val 6 | self.children = children 7 | """ 8 | class Solution: 9 | cache = {} 10 | 11 | def maxDepth(self, root: 'Node') -> int: 12 | if not root: 13 | return 0 14 | 15 | if not root.children: 16 | return 1 17 | 18 | if root in self.cache: 19 | return cache[root] 20 | 21 | result = max([self.maxDepth(c) for c in root.children]) + 1 22 | self.cache[root] = result 23 | 24 | return result 25 | -------------------------------------------------------------------------------- /algorithms/middle_of_linked_list.py: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/problems/middle-of-the-linked-list/submissions/ 2 | # Definition for singly-linked list. 3 | # class ListNode: 4 | # def __init__(self, x): 5 | # self.val = x 6 | # self.next = None 7 | 8 | class Solution: 9 | def middleNode(self, head: ListNode) -> ListNode: 10 | fast = slow = head 11 | 12 | while fast and fast.next: 13 | slow = slow.next 14 | fast = fast.next.next 15 | 16 | return slow 17 | -------------------------------------------------------------------------------- /algorithms/min_height_of_binary_tree.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | class TreeNode: 3 | def __init__(self, x): 4 | self.val = x 5 | self.left = None 6 | self.right = None 7 | 8 | 9 | class Solution: 10 | def minDepth(self, root: TreeNode) -> int: 11 | if not root: 12 | return 0 13 | 14 | if not (root.left or root.right): 15 | return 1 16 | 17 | if not root.right: 18 | return self.minDepth(root.left) + 1 19 | 20 | if not root.left: 21 | return self.minDepth(root.right) + 1 22 | 23 | return min([ 24 | self.minDepth(root.left) + 1, 25 | self.minDepth(root.right) + 1, 26 | ]) 27 | -------------------------------------------------------------------------------- /algorithms/mountain_array.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def validMountainArray(self, A: List[int]) -> bool: 3 | n = len(A) 4 | if n < 3: 5 | return False 6 | 7 | increasing = True 8 | 9 | for i in range(1, n-1): 10 | if increasing and A[i-1] < A[i] < A[i+1]: 11 | continue 12 | 13 | if increasing and A[i-1] < A[i] > A[i+1]: 14 | increasing = False 15 | continue 16 | 17 | if not increasing and A[i-1] > A[i] > A[i+1]: 18 | continue 19 | 20 | return False 21 | 22 | return not increasing 23 | -------------------------------------------------------------------------------- /algorithms/multiply_strings.py: -------------------------------------------------------------------------------- 1 | from itertools import zip_longest 2 | 3 | class Solution: 4 | def multiply(self, num1: str, num2: str) -> str: 5 | result = "" 6 | 7 | for i, d in enumerate(reversed(num1)): 8 | product = self.multiplyByDigit(d, num2) 9 | product += "0" * i 10 | result = self.addStrings(product, result) 11 | 12 | result = result.lstrip("0") 13 | return result or "0" 14 | 15 | def multiplyByDigit(self, d: str, num: str): 16 | carry = 0 17 | d = int(d) 18 | result = "" 19 | 20 | for c in reversed(num): 21 | product = int(c) * d + carry 22 | carry = product // 10 23 | result = str(product % 10) + result 24 | 25 | if carry: 26 | result = str(carry) + result 27 | 28 | return result 29 | 30 | def addStrings(self, num1, num2): 31 | carry = 0 32 | result = "" 33 | num1, num2 = reversed(num1), reversed(num2) 34 | 35 | for c1, c2 in zip_longest(num1, num2, fillvalue="0"): 36 | d1, d2 = int(c1), int(c2) 37 | sum_ = d1 + d2 + carry 38 | carry = sum_ // 10 39 | result = str(sum_ % 10) + result 40 | 41 | if carry: 42 | result = str(carry) + result 43 | 44 | return result 45 | -------------------------------------------------------------------------------- /algorithms/path_sum.py: -------------------------------------------------------------------------------- 1 | class TreeNode: 2 | def __init__(self, x): 3 | self.val = x 4 | self.left = None 5 | self.right = None 6 | 7 | 8 | class Solution: 9 | def hasPathSum(self, root: TreeNode, sum_: int) -> bool: 10 | if not root: 11 | return False # true would be better I guess 12 | 13 | if not (root.left or root.right): 14 | return sum_ == root.val 15 | 16 | remaining_sum = sum_ - root.val 17 | if root.left and self.hasPathSum(root.left, remaining_sum): 18 | return True 19 | 20 | if root.right and self.hasPathSum(root.right, remaining_sum): 21 | return True 22 | 23 | return False 24 | 25 | 26 | if __name__ == "__main__": 27 | tree = TreeNode(5) 28 | tree.left = TreeNode(4) 29 | tree.right = TreeNode(8) 30 | tree.left.left = TreeNode(11) 31 | tree.right.left = TreeNode(13) 32 | tree.right.right = TreeNode(4) 33 | tree.left.left.left = TreeNode(7) 34 | tree.left.left.right = TreeNode(2) 35 | 36 | s = Solution() 37 | 38 | print(s.hasPathSum(tree, 22)) 39 | -------------------------------------------------------------------------------- /algorithms/power_of_four.py: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/problems/power-of-four/submissions/ 2 | 3 | # todo: can this be done with bithacks? 4 | class Solution: 5 | def isPowerOfFour(self, num: int) -> bool: 6 | if num == 1: 7 | return True 8 | 9 | if num % 4 != 0 or num == 0: 10 | return False 11 | 12 | return self.isPowerOfFour(num // 4) 13 | -------------------------------------------------------------------------------- /algorithms/product_of_array_except_self.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def productExceptSelf(self, nums: List[int]) -> List[int]: 3 | zeros = nums.count(0) 4 | if zeros > 1: 5 | return [0 for _ in nums] 6 | 7 | product = 1 8 | for n in nums: 9 | if n != 0: 10 | product = product * n 11 | 12 | if zeros == 1: 13 | return [0 if n != 0 else product for n in nums] 14 | 15 | for i, n in enumerate(nums): 16 | nums[i] = int(product / n) 17 | 18 | return nums 19 | -------------------------------------------------------------------------------- /algorithms/ransom_note.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def canConstruct(self, ransomNote: str, magazine: str) -> bool: 3 | difference = collections.Counter(ransomNote) - collections.Counter(magazine) 4 | 5 | return not difference 6 | -------------------------------------------------------------------------------- /algorithms/remove_linked_list_elements.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 | class Solution: 8 | def removeElements(self, head: ListNode, val: int) -> ListNode: 9 | l = head 10 | prev = None 11 | 12 | while l: 13 | if prev and l.val == val: 14 | prev.next = l.next 15 | l = l.next 16 | continue 17 | 18 | prev = l 19 | l = l.next 20 | 21 | if head and head.val == val: 22 | return head.next 23 | 24 | return head 25 | -------------------------------------------------------------------------------- /algorithms/reverse_words.py: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/problems/reverse-words-in-a-string/submissions/ 2 | 3 | 4 | class Solution: 5 | def reverseWords(self, s: str) -> str: 6 | words = s.strip().split() 7 | return " ".join(reversed(words)) 8 | -------------------------------------------------------------------------------- /algorithms/rotate_linked_list.py: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/problems/rotate-list/submissions/ 2 | 3 | # Definition for singly-linked list. 4 | class ListNode: 5 | def __init__(self, x): 6 | self.val = x 7 | self.next = None 8 | 9 | 10 | class Solution: 11 | def rotateRight(self, head: ListNode, k: int) -> ListNode: 12 | if k == 0 or not head: 13 | return head 14 | 15 | l = self.ll2l(head) 16 | l = self.rotateList(l, k) 17 | ll = self.l2ll(l) 18 | 19 | return ll 20 | 21 | @staticmethod 22 | def ll2l(ll): 23 | l = [] 24 | 25 | while ll: 26 | l.append(ll.val) 27 | ll = ll.next 28 | 29 | return l 30 | 31 | @staticmethod 32 | def l2ll(l): 33 | head = ListNode(l[0]) 34 | current = head 35 | 36 | for li in l[1:]: 37 | current.next = ListNode(li) 38 | current = current.next 39 | 40 | return head 41 | 42 | 43 | @staticmethod 44 | def rotateList(l, k): 45 | k = k % len(l) 46 | l = l[len(l) - k:] + l[:len(l) - k] 47 | 48 | return l 49 | -------------------------------------------------------------------------------- /algorithms/rotated_digits.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def rotatedDigits(self, N: int) -> int: 3 | rotatables = {'2', '5', '6', '9'} 4 | non_rotatables = {'3', '4', '7'} 5 | counter = 0 6 | 7 | for i in range(1, N+1): 8 | if any([digit in str(i) for digit in non_rotatables]): 9 | continue 10 | 11 | if any([digit in str(i) for digit in rotatables]): 12 | counter += 1 13 | 14 | return counter 15 | -------------------------------------------------------------------------------- /algorithms/search_in_bst.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | 9 | class Solution: 10 | def searchBST(self, root: TreeNode, val: int) -> TreeNode: 11 | if not root: 12 | return None 13 | 14 | if root.val < val: 15 | return self.searchBST(root.right, val) 16 | 17 | if root.val > val: 18 | return self.searchBST(root.left, val) 19 | 20 | return root 21 | -------------------------------------------------------------------------------- /algorithms/sequentials_digits.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def sequentialDigits(self, low: int, high: int) -> List[int]: 3 | result = [] 4 | digits = "123456789" 5 | low_size = len(str(low)) 6 | high_size = len(str(high)) 7 | 8 | for i in range(low_size, high_size+1): 9 | for j in range(i, 10): 10 | num = int(digits[j-i:j]) 11 | if low <= num <= high: 12 | result.append(num) 13 | 14 | return result 15 | -------------------------------------------------------------------------------- /algorithms/smallest_sufficient_team.py: -------------------------------------------------------------------------------- 1 | """ 2 | https://leetcode.com/problems/smallest-sufficient-team/ 3 | [ 4 | 1 1 0 1 0 0 5 | 1 0 0 1 0 0 6 | 0 1 1 0 0 0 7 | 0 1 0 0 1 0 8 | 0 0 1 0 1 1 9 | 0 0 0 1 1 1 10 | ] 11 | """ 12 | 13 | def skill_sum(person, skill_map): 14 | return sum([skill_map[skill] for skill in person]) 15 | 16 | 17 | def find_team(skills, people): 18 | # TODO 19 | return [] 20 | 21 | 22 | def smallestSufficientTeam(req_skills, people): 23 | if not req_skills: 24 | return [] 25 | 26 | skill_map = {} 27 | skills_sum = (1 << len(req_skills)) - 1 28 | for index, skill in enumerate(req_skills): 29 | skill_map[skill] = 1 << index 30 | 31 | people = [skill_sum(person, skill_map) for person in people] 32 | team = find_team(skills_sum, people) 33 | 34 | return team 35 | 36 | 37 | if __name__ == '__main__': 38 | cases = [ 39 | [(["java","nodejs","reactjs"], [["java"],["nodejs"],["nodejs","reactjs"]]), [0,2]], 40 | [(["algorithms","math","java","reactjs","csharp","aws"], [["algorithms","math","java"],["algorithms","math","reactjs"],["java","csharp","aws"],["reactjs","csharp"],["csharp","math"],["aws","java"]]), [1,2]], 41 | ] 42 | 43 | for case in cases: 44 | result = set(smallestSufficientTeam(*case[0])) 45 | expected = set(case[1]) 46 | print("PASS" if result == expected else "FAIL") 47 | -------------------------------------------------------------------------------- /algorithms/sort_characters_by_frequency.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | from collections import Counter 3 | 4 | 5 | class Solution: 6 | def frequencySort2(self, s: str) -> str: 7 | result = '' 8 | counter = Counter(s) 9 | 10 | for char in sorted(counter, key=lambda k: -counter[k]): 11 | result += char * counter[char] 12 | 13 | return result 14 | -------------------------------------------------------------------------------- /algorithms/squares_of_sorted_array.go: -------------------------------------------------------------------------------- 1 | func sortedSquares(A []int) []int { 2 | results := make([]int, len(A)) 3 | index := len(A) - 1 4 | negative, positive := 0, len(A) - 1 5 | 6 | for index >= 0 { 7 | if square(A[negative]) > square(A[positive]) { 8 | results[index] = square(A[negative]) 9 | negative += 1 10 | } else { 11 | results[index] = square(A[positive]) 12 | positive -= 1 13 | } 14 | 15 | index -= 1 16 | } 17 | 18 | return results 19 | } 20 | 21 | func square(n int) int { 22 | return n * n 23 | } 24 | -------------------------------------------------------------------------------- /algorithms/squares_of_sorted_array.py: -------------------------------------------------------------------------------- 1 | def sortedSquares(A: List[int]) -> List[int]: 2 | index = len(A) - 1 3 | results = [0 for _ in A] 4 | negative, positive = 0, len(A) - 1 5 | while index >= 0: 6 | if abs(A[negative]) > A[positive]: 7 | results[index] = A[negative] ** 2 8 | negative += 1 9 | else: 10 | results[index] = A[positive] ** 2 11 | positive -= 1 12 | index -= 1 13 | return results 14 | -------------------------------------------------------------------------------- /algorithms/string_compression.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def compress(self, chars: List[str]) -> int: 3 | prev = chars[0] 4 | i = count = 0 5 | 6 | for char in chars: 7 | if char == prev: 8 | count += 1 9 | continue 10 | 11 | chars[i] = prev 12 | i += 1 13 | 14 | if count != 1: 15 | for digit in str(count): 16 | chars[i] = digit 17 | i += 1 18 | 19 | count = 1 20 | prev = char 21 | 22 | chars[i] = prev 23 | i += 1 24 | if count != 1: 25 | for digit in str(count): 26 | chars[i] = digit 27 | i += 1 28 | 29 | return i 30 | -------------------------------------------------------------------------------- /algorithms/third_max.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | from typing import List 3 | 4 | 5 | class Solution: 6 | def thirdMax(self, nums: List[int]) -> int: 7 | three_largest = heapq.nlargest(3, set(nums)) 8 | 9 | if len(three_largest) < 3: 10 | return three_largest[0] 11 | 12 | return three_largest[2] 13 | 14 | 15 | if __name__ == '__main__': 16 | s = Solution() 17 | cases = [ 18 | ([3, 2, 1], 1), 19 | ([1, 2], 2), 20 | ([2, 2, 3, 1], 1), 21 | ] 22 | 23 | for case in cases: 24 | print(s.thirdMax(case[0]), case[1]) 25 | print("PASS" if s.thirdMax(case[0]) == case[1] else "FAIL") 26 | -------------------------------------------------------------------------------- /algorithms/uni_valued_binary_tree.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, val=0, left=None, right=None): 4 | # self.val = val 5 | # self.left = left 6 | # self.right = right 7 | class Solution: 8 | def isUnivalTree(self, root: TreeNode) -> bool: 9 | if not root: return True 10 | return self.dfs(root, root.val) 11 | 12 | def dfs(self, root: TreeNode, val: int): 13 | if not root: return True 14 | return ( 15 | root.val == val and \ 16 | self.dfs(root.left, val) and \ 17 | self.dfs(root.right, val) 18 | ) 19 | -------------------------------------------------------------------------------- /algorithms/valid_boomerang.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isBoomerang(self, points: List[List[int]]) -> bool: 3 | points = [tuple(point) for point in points] 4 | if len(set(points)) != 3: 5 | return False 6 | 7 | if points[0][1] == points[1][1] and points[1][1] == points[2][1]: 8 | return False 9 | 10 | if points[0][1] == points[1][1] or points[1][1] == points[2][1]: 11 | return True 12 | 13 | k1 = (points[0][0] - points[1][0]) / (points[0][1] - points[1][1]) 14 | k2 = (points[1][0] - points[2][0]) / (points[1][1] - points[2][1]) 15 | 16 | return k1 != k2 17 | -------------------------------------------------------------------------------- /algorithms/valid_perfect_square.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isPerfectSquare(self, num: int) -> bool: 3 | root = self.getSquareRoot(num) 4 | return num == root * root 5 | 6 | def getSquareRoot(self, num: int) -> int: 7 | result = num 8 | 9 | for _ in range(100): 10 | result = 0.5 * (result + num/result) 11 | 12 | return int(result) 13 | -------------------------------------------------------------------------------- /algorithms/verify_alien_dictionary.py: -------------------------------------------------------------------------------- 1 | def isAlienSorted(words, rder): 2 | orders = {l: i for i, l in enumerate(order)} 3 | prev_word_val = () 4 | 5 | for word in words: 6 | word_val = tuple([orders[l] for l in word]) 7 | if prev_word_val > word_val: 8 | return False 9 | prev_word_val = word_val 10 | 11 | return True 12 | -------------------------------------------------------------------------------- /algorithms/word_break.py: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/problems/word-break/ 2 | 3 | memory = {} 4 | 5 | def wordBreak(word: str, words: list) -> bool: 6 | if word in memory: 7 | return memory[word] 8 | 9 | if not word: 10 | memory[word] = True 11 | return True 12 | 13 | start_words = [s for s in words if word.startswith(s)] 14 | if not start_words: 15 | memory[word] = False 16 | return False 17 | 18 | for s in start_words: 19 | remaining = word[len(s):] 20 | if wordBreak(remaining, words): 21 | memory[word] = True 22 | return True 23 | 24 | memory[word] = False 25 | return False 26 | 27 | 28 | if __name__ == '__main__': 29 | cases = [ 30 | [("cars", ["car", "ca", "rs"]), True], 31 | [("leetcode", ["leet", "code"]), True], 32 | [("applepenapple", ["apple", "pen"]), True], 33 | [("catsandog", ["cats", "dog", "sand", "and", "cat"]), False], 34 | [("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", ["aa","aaa","aaaa","aaaaa","aaaaaa","aaaaaaa","aaaaaaaa","aaaaaaaaa","aaaaaaaaaa","ba"]), False] 35 | ] 36 | 37 | for case in cases: 38 | print("PASS" if wordBreak(*case[0])==case[1] else "FAIL") 39 | -------------------------------------------------------------------------------- /algorithms/word_break_ii.py: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/problems/word-break-ii 2 | 3 | def wordBreak(word: str, words: list) -> list: 4 | if not word: 5 | return [''] 6 | 7 | start_words = [s for s in words if word.startswith(s)] 8 | if not start_words: 9 | return [] 10 | 11 | sentences = [] 12 | for s in start_words: 13 | remaining = word[len(s):] 14 | remaining_sentences = wordBreak(remaining, words) 15 | sentences.extend([(s+' '+rs).strip() for rs in remaining_sentences]) 16 | 17 | return sentences 18 | 19 | 20 | if __name__ == '__main__': 21 | cases = [ 22 | [("cars", ["car", "ca", "rs"]), ["ca rs"]], 23 | [("leetcode", ["leet", "code"]), ["leet code"]], 24 | [("applepenapple", ["apple", "pen"]), ["apple pen apple"]], 25 | [("catsanddog", ["cats", "dog", "sand", "and", "cat"]), ["cats and dog", "cat sand dog"]], 26 | [("pineapplepenapple", ["apple", "pen", "applepen", "pine", "pineapple"]), ["pine apple pen apple", "pineapple pen apple", "pine applepen apple"]] 27 | ] 28 | 29 | for case in cases: 30 | result = set(wordBreak(*case[0])) 31 | expected = set(case[1]) 32 | print("PASS" if result==expected else "FAIL", result) 33 | -------------------------------------------------------------------------------- /algorithms/word_pattern.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def wordPattern(self, pattern: str, string: str) -> bool: 3 | pattern_map = {} 4 | wordset = set() 5 | words = string.split() 6 | 7 | if len(words) != len(pattern): 8 | return False 9 | 10 | for char, word in zip(pattern, words): 11 | if char not in pattern_map and word in wordset: 12 | return False 13 | 14 | if char not in pattern_map: 15 | pattern_map[char] = word 16 | wordset.add(word) 17 | continue 18 | 19 | if pattern_map[char] != word: 20 | return False 21 | 22 | return True 23 | -------------------------------------------------------------------------------- /algorithms/x_of_a_kind_in_a_deck_of_cards.py: -------------------------------------------------------------------------------- 1 | from functools import reduce 2 | 3 | 4 | class Solution: 5 | def hasGroupsSizeX(self, deck: List[int]) -> bool: 6 | counter = collections.Counter(deck) 7 | 8 | cards = list(counter.values()) 9 | if len(cards) == 0: 10 | return False 11 | 12 | return reduce(math.gcd, cards) > 1 13 | -------------------------------------------------------------------------------- /algorithms/xor-operation-in-an-array.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def xorOperation(self, n: int, start: int) -> int: 3 | xor_sum = start 4 | for i in range(1, n): 5 | xor_sum ^= (start + 2*i) 6 | 7 | return xor_sum 8 | -------------------------------------------------------------------------------- /august_challenge/01_detect_capital.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def detectCapitalUse(self, word: str) -> bool: 3 | return word in ( 4 | word.upper(), 5 | word.lower(), 6 | word.capitalize(), 7 | ) 8 | -------------------------------------------------------------------------------- /august_challenge/03_valid_palindrome.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isPalindrome(self, s: str) -> bool: 3 | s = s.lower() 4 | clean = '' 5 | 6 | for c in s: 7 | if c.isalnum(): 8 | clean += c 9 | 10 | return clean == clean[::-1] 11 | -------------------------------------------------------------------------------- /august_challenge/04_power_of_four.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isPowerOfFour(self, num: int) -> bool: 3 | return num % 3 == 1 and (num - 1) & num == 0 4 | -------------------------------------------------------------------------------- /august_challenge/06_find_duplicates.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def findDuplicates(self, nums: List[int]) -> List[int]: 3 | result = [] 4 | n = len(nums) 5 | 6 | for num in nums: 7 | if nums[abs(num) - 1] < 0: 8 | result.append(abs(num)) 9 | nums[abs(num) - 1] = -nums[abs(num) - 1] 10 | 11 | return result 12 | -------------------------------------------------------------------------------- /database/big_countries.sql: -------------------------------------------------------------------------------- 1 | -- https://leetcode.com/problems/big-countries/ 2 | SELECT name, population, area FROM World 3 | WHERE area > 3000000 or population > 25000000 4 | -------------------------------------------------------------------------------- /database/combine_two_tables.sql: -------------------------------------------------------------------------------- 1 | -- https://leetcode.com/problems/combine-two-tables/submissions/ 2 | SELECT Person.FirstName, Person.LastName, Address.City, Address.State 3 | FROM Person 4 | LEFT JOIN Address ON Person.PersonId = Address.PersonId 5 | -------------------------------------------------------------------------------- /database/customer_who_never_ordered.sql: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/problems/customers-who-never-order/submissions/ 2 | 3 | -- SELECT customers.Name as Customers FROM customers WHERE customers.Id NOT IN ( 4 | -- SELECT orders.CustomerId FROM orders 5 | -- ) 6 | 7 | SELECT customers.Name as Customers FROM customers 8 | LEFT JOIN orders ON customers.Id = orders.CustomerId 9 | WHERE orders.Id is NULL; 10 | -------------------------------------------------------------------------------- /database/dublicate_emails.sql: -------------------------------------------------------------------------------- 1 | -- https://leetcode.com/problems/duplicate-emails/ 2 | 3 | SELECT Email from Person 4 | GROUP BY Email 5 | HAVING COUNT(Email) > 1 6 | -------------------------------------------------------------------------------- /database/employees_earning_more_than_theirs_managers.sql: -------------------------------------------------------------------------------- 1 | -- https://leetcode.com/problems/employees-earning-more-than-their-managers/submissions/ 2 | SELECT Employee.Name as Employee FROM Employee 3 | INNER JOIN Employee as Manager ON Employee.ManagerId = Manager.id 4 | WHERE Employee.Salary > Manager.Salary 5 | -------------------------------------------------------------------------------- /database/not_boring_movies.sql: -------------------------------------------------------------------------------- 1 | SELECT * FROM cinema WHERE id%2=1 and description!='boring' ORDER BY rating desc 2 | -------------------------------------------------------------------------------- /database/rising_temperature.sql: -------------------------------------------------------------------------------- 1 | SELECT t1.id as id 2 | FROM ( 3 | SELECT * FROM weather 4 | ) as t1 5 | INNER JOIN ( 6 | SELECT * FROM weather 7 | ) as t2 8 | ON t1.recorddate - INTERVAL 1 DAY = t2.recorddate 9 | WHERE t1.temperature > t2.temperature; 10 | -------------------------------------------------------------------------------- /database/second_highest_salary.sql: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/problems/second-highest-salary/submissions/ 2 | # Write your MySQL query statement below 3 | SELECT MAX(Salary) AS SecondHighestSalary 4 | FROM Employee 5 | WHERE Salary < ( 6 | SELECT MAX(SALARY) FROM Employee 7 | ) 8 | -------------------------------------------------------------------------------- /june_challenge/01_invert_binary_tree.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution: 9 | def invertTree(self, root: TreeNode) -> TreeNode: 10 | if not root: 11 | return 12 | 13 | inverted = TreeNode(root.val) 14 | if root.left: 15 | inverted.right = self.invertTree(root.left) 16 | 17 | if root.right: 18 | inverted.left = self.invertTree(root.right) 19 | 20 | return inverted 21 | -------------------------------------------------------------------------------- /june_challenge/02_delete_node_in_linked_list.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 | class Solution: 8 | def deleteNode(self, node): 9 | """ 10 | :type node: ListNode 11 | :rtype: void Do not return anything, modify node in-place instead. 12 | """ 13 | node.val = node.next.val 14 | node.next = node.next.next 15 | -------------------------------------------------------------------------------- /june_challenge/03_two_city_scheduling.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def twoCitySchedCost(self, costs: List[List[int]]) -> int: 3 | n = len(costs) 4 | total_cost = 0 5 | costs.sort(key=lambda cost: cost[0] - cost[1]) 6 | 7 | total_cost += sum([cost[0] for cost in costs[:n//2]]) 8 | total_cost += sum([cost[1] for cost in costs[n//2:]]) 9 | 10 | return total_cost 11 | -------------------------------------------------------------------------------- /june_challenge/04_reverse_string.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def reverseString(self, s: List[str]) -> None: 3 | """ 4 | Do not return anything, modify s in-place instead. 5 | """ 6 | n = len(s) 7 | 8 | for i in range(n//2): 9 | s[i], s[n-i-1] = s[n-i-1], s[i] 10 | -------------------------------------------------------------------------------- /june_challenge/05_random_with_weight.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | class Solution: 5 | 6 | def __init__(self, w: List[int]): 7 | self.indexes = list(range(len(w))) 8 | self.weights = w 9 | 10 | def pickIndex(self) -> int: 11 | return random.choices(self.indexes, self.weights)[0] 12 | -------------------------------------------------------------------------------- /june_challenge/06_queue_reconstruction_by_height.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]: 3 | n = len(people) 4 | queue = [] 5 | people.sort(key=lambda x: (-x[0], x[1])) 6 | 7 | for height, position in people: 8 | queue.insert(position, [height, position]) 9 | 10 | return queue 11 | -------------------------------------------------------------------------------- /june_challenge/07_coin_change_2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # Dynamic Programming 3 | def changeDP(self, amount: int, coins: List[int]) -> int: 4 | dp = [0] * (amount + 1) 5 | dp[0] = 1 6 | 7 | for coin in coins: 8 | for i in range(coin, amount+1): 9 | dp[i] += dp[i-coin] 10 | 11 | return dp[-1] 12 | 13 | # Recursion 14 | def __init__(self): 15 | self.memo = {} 16 | 17 | def changeRec(self, amount: int, coins: List[int]) -> int: 18 | if (amount, tuple(coins)) in self.memo: 19 | return self.memo[amount, tuple(coins)] 20 | 21 | if amount == 0: 22 | return 1 23 | 24 | if amount < 0 or not coins: 25 | return 0 26 | 27 | result = self.change(amount, coins[:-1]) + self.change(amount-coins[-1], coins) 28 | self.memo[amount, tuple(coins)] = result 29 | 30 | return result 31 | -------------------------------------------------------------------------------- /june_challenge/08_power_of_two.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isPowerOfTwo(self, n: int) -> bool: 3 | if n < 1: 4 | return False 5 | 6 | return bin(n).count('1') == 1 7 | -------------------------------------------------------------------------------- /june_challenge/09_is_subsequence.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isSubsequence(self, s: str, t: str) -> bool: 3 | i = 0 4 | for char in t: 5 | if i < len(s) and s[i] == char: 6 | i += 1 7 | 8 | return i == len(s) 9 | -------------------------------------------------------------------------------- /june_challenge/10_insert_position.py: -------------------------------------------------------------------------------- 1 | import bisect 2 | 3 | 4 | class Solution: 5 | def searchInsert(self, nums: List[int], target: int) -> int: 6 | return bisect.bisect_left(nums, target) 7 | -------------------------------------------------------------------------------- /june_challenge/11_sort_colors.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def sortColors(self, nums: List[int]) -> None: 3 | """ 4 | Do not return anything, modify nums in-place instead. 5 | """ 6 | n = len(nums) 7 | j, k = 0, n - 1 8 | 9 | for i in range(n): 10 | if i == k + 1: 11 | break 12 | if nums[i] == 0: 13 | nums[j], nums[i] = nums[i], nums[j] 14 | j += 1 15 | elif nums[i] == 2: 16 | nums[k], nums[i] = nums[i], nums[k] 17 | k -= 1 18 | -------------------------------------------------------------------------------- /june_challenge/12_randomized_set.py: -------------------------------------------------------------------------------- 1 | class RandomizedSet: 2 | 3 | def __init__(self): 4 | """ 5 | Initialize your data structure here. 6 | """ 7 | self.dict = dict() 8 | self.list = list() 9 | 10 | def insert(self, val: int) -> bool: 11 | """ 12 | Inserts a value to the set. Returns true if the set did not already contain the specified element. 13 | """ 14 | if val not in self.dict: 15 | self.dict[val] = len(self.list) 16 | self.list.append(val) 17 | 18 | return True 19 | 20 | return False 21 | 22 | def remove(self, val: int) -> bool: 23 | """ 24 | Removes a value from the set. Returns true if the set contained the specified element. 25 | """ 26 | if val in self.dict: 27 | index = self.dict.pop(val) 28 | self.list[index] = self.list[-1] 29 | 30 | last_val = self.list.pop() 31 | if last_val != val: 32 | self.dict[last_val] = index 33 | 34 | return True 35 | 36 | return False 37 | 38 | def getRandom(self) -> int: 39 | """ 40 | Get a random element from the set. 41 | """ 42 | return random.choice(self.list) 43 | -------------------------------------------------------------------------------- /june_challenge/13_divisible_subset.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def largestDivisibleSubset(self, nums: List[int]) -> List[int]: 3 | if not nums: 4 | return [] 5 | 6 | n = len(nums) 7 | nums.sort() 8 | div_count = [1 for _ in range(n)] 9 | prev = [-1 for _ in range(n)] 10 | max_index = 0 11 | 12 | for i in range(n): 13 | for j in range(i): 14 | if nums[i] % nums[j] == 0: 15 | if div_count[i] < div_count[j] + 1: 16 | div_count[i] = div_count[j] + 1 17 | prev[i] = j 18 | 19 | if div_count[max_index] < div_count[i]: 20 | max_index = i 21 | 22 | result = [] 23 | k = max_index 24 | while k >= 0: 25 | result.append(nums[k]) 26 | k = prev[k] 27 | 28 | return result 29 | -------------------------------------------------------------------------------- /june_challenge/15_search_in_bst.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class Solution: 9 | def searchBST(self, root: TreeNode, val: int) -> TreeNode: 10 | if not root: 11 | return None 12 | 13 | if root.val < val: 14 | return self.searchBST(root.right, val) 15 | 16 | if root.val > val: 17 | return self.searchBST(root.left, val) 18 | 19 | return root 20 | -------------------------------------------------------------------------------- /june_challenge/16_validate_ip_address.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def validIPAddress(self, IP: str) -> str: 3 | def validate_IPv4_regex(chunks): 4 | return re.match(r'(' + IPv4_chunk_pattern + ')', chunk) 5 | 6 | # validating single IPv6 chunk using Regular Expression 7 | def validate_IPv6_regex(chunk): 8 | return re.match(r'(' + IPv6_chunk_pattern + ')', chunk) 9 | 10 | IPv4_chunk_pattern = "^([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$" 11 | IPv6_chunk_pattern = "^([0-9a-fA-F]{1,4})$" 12 | 13 | if IP.count('.') == 3: 14 | for chunk in IP.split("."): 15 | if not validate_IPv4_regex(chunk): 16 | return "Neither" 17 | return "IPv4" 18 | elif IP.count(':') == 7: 19 | for chunk in IP.split(":"): 20 | if not validate_IPv6_regex(chunk): 21 | return "Neither" 22 | return "IPv6" 23 | 24 | return "Neither" 25 | -------------------------------------------------------------------------------- /june_challenge/17_surrounded_regions.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def solve(self, board): 3 | if not board: return 0 4 | self.board, self.M, self.N = board, len(board), len(board[0]) 5 | 6 | for i in range(0, self.M): 7 | self.dfs(i,0) 8 | self.dfs(i,self.N-1) 9 | 10 | for j in range(0, self.N): 11 | self.dfs(0,j) 12 | self.dfs(self.M-1,j) 13 | 14 | for i,j in product(range(self.M), range(self.N)): 15 | board[i][j] = "X" if board[i][j] != "T" else "O" 16 | 17 | def dfs(self, i, j): 18 | if i<0 or j<0 or i>=self.M or j>=self.N or self.board[i][j] != "O": 19 | return 20 | 21 | self.board[i][j] = 'T' 22 | neighbours = [(i+1,j), (i-1,j), (i,j-1), (i,j+1)] 23 | 24 | for x, y in neighbours: 25 | self.dfs(x, y) 26 | -------------------------------------------------------------------------------- /june_challenge/18_h_index.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def hIndex(self, citations: List[int]) -> int: 3 | n , left , right = len(citations) , 0 , len(citations) 4 | while left < right: 5 | mid = left + (right - left) // 2 6 | num_greater = n - mid 7 | if num_greater <= citations[mid]: 8 | right = mid 9 | else: 10 | left = mid + 1 11 | return n - left 12 | -------------------------------------------------------------------------------- /june_challenge/19_longest_duplicate_substring.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def RabinKarp(self,text, M, q): 3 | if M == 0: return True 4 | h, t, d = (1 << (8 * M-8)) % q, 0, 256 5 | 6 | dict_ = defaultdict(list) 7 | 8 | for i in range(M): 9 | t = (d * t + ord(text[i])) % q 10 | 11 | dict_[t].append(i-M+1) 12 | 13 | for i in range(len(text) - M): 14 | t = (d*(t-ord(text[i])*h) + ord(text[i + M]))% q 15 | for j in dict_[t]: 16 | if text[i+1:i+M+1] == text[j:j+M]: 17 | return (True, text[j:j+M]) 18 | dict_[t].append(i+1) 19 | return (False, "") 20 | 21 | def longestDupSubstring(self, S): 22 | begin, end = 0, len(S) 23 | q = (1<<31) - 1 24 | Found = "" 25 | while begin + 1 < end: 26 | mid = (begin + end)//2 27 | isFound, candidate = self.RabinKarp(S, mid, q) 28 | if isFound: 29 | begin, Found = mid, candidate 30 | else: 31 | end = mid 32 | 33 | return Found -------------------------------------------------------------------------------- /june_challenge/20_permutations_sequence.py: -------------------------------------------------------------------------------- 1 | from itertools import permutations 2 | 3 | class Solution: 4 | def getPermutation(self, n: int, k: int) -> str: 5 | elems = list(permutations(range(1,n+1)))[k-1] 6 | elems = [str(elem) for elem in elems] 7 | return "".join(elems) 8 | -------------------------------------------------------------------------------- /june_challenge/21_dungeon_game.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def calculateMinimumHP(self, dungeon): 3 | m, n = len(dungeon), len(dungeon[0]) 4 | dp = [[float("inf")]*(n+1) for _ in range(m+1)] 5 | dp[m-1][n], dp[m][n-1] = 1, 1 6 | 7 | for i in range(m-1,-1,-1): 8 | for j in range(n-1,-1,-1): 9 | dp[i][j] = max(min(dp[i+1][j], dp[i][j+1]) - dungeon[i][j],1) 10 | 11 | return dp[0][0] 12 | -------------------------------------------------------------------------------- /may_challenge/01_first_bad_version.py: -------------------------------------------------------------------------------- 1 | # The isBadVersion API is already defined for you. 2 | # @param version, an integer 3 | # @return a bool 4 | # def isBadVersion(version): 5 | 6 | class Solution: 7 | def firstBadVersion(self, n): 8 | """ 9 | :type n: int 10 | :rtype: int 11 | """ 12 | min_ = 0 13 | max_ = n 14 | 15 | while min_ < max_: 16 | middle = (min_ + max_ + 1) // 2 17 | if isBadVersion(middle): 18 | max_ = middle 19 | else: 20 | min_ = middle 21 | 22 | if max_ - min_ == 1: 23 | if isBadVersion(min_): 24 | return min_ 25 | 26 | return max_ 27 | 28 | return middle 29 | -------------------------------------------------------------------------------- /may_challenge/02_jewels_and_stones.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def numJewelsInStones(self, J: str, S: str) -> int: 3 | J = set(J) 4 | count = 0 5 | 6 | for s in S: 7 | if s in J: 8 | count += 1 9 | 10 | return count 11 | -------------------------------------------------------------------------------- /may_challenge/03_ransom_note.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def canConstruct(self, ransomNote: str, magazine: str) -> bool: 3 | difference = collections.Counter(ransomNote) - collections.Counter(magazine) 4 | 5 | return not difference 6 | -------------------------------------------------------------------------------- /may_challenge/04_number_complement.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def findComplement(self, num: int) -> int: 3 | return int( 4 | bin(num)[2:].replace('0', '*').replace('1', '0').replace('*', '1'), 2 5 | ) 6 | -------------------------------------------------------------------------------- /may_challenge/05_first_unique_char.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def firstUniqChar(self, s: str) -> int: 3 | counter = collections.Counter(s) 4 | 5 | for index, char in enumerate(s): 6 | if counter[char] == 1: 7 | return index 8 | 9 | return -1 10 | 11 | -------------------------------------------------------------------------------- /may_challenge/06_majority_element.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def majorityElement(self, nums: List[int]) -> int: 3 | nums.sort() 4 | length = len(nums) 5 | 6 | return nums[length // 2] 7 | -------------------------------------------------------------------------------- /may_challenge/07_cousins_in_binary_tree.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | # class TreeNode: 3 | # def __init__(self, val=0, left=None, right=None): 4 | # self.val = val 5 | # self.left = left 6 | # self.right = right 7 | class Solution: 8 | def isCousins(self, root: TreeNode, x: int, y: int) -> bool: 9 | if not root: 10 | return False 11 | 12 | queue = collections.deque() 13 | queue.append((root, 0, None)) 14 | nodes = {} 15 | 16 | while queue: 17 | node, level, parent = queue.popleft() 18 | nodes[node.val] = (level, parent) 19 | 20 | if node.left: 21 | queue.append((node.left, level+1, node)) 22 | 23 | if node.right: 24 | queue.append((node.right, level+1, node)) 25 | 26 | return nodes[x][0] == nodes[y][0] and nodes[x][1] != nodes[y][1] 27 | -------------------------------------------------------------------------------- /may_challenge/08_check_straight_line.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def checkStraightLine(self, coordinates: List[List[int]]) -> bool: 3 | if len(coordinates) < 2: 4 | return True 5 | 6 | first, last = coordinates[0], coordinates[-1] 7 | if first[0] == last[0]: 8 | for coordinate in coordinates: 9 | if coordinate[1] != first[1]: 10 | return False 11 | return True 12 | 13 | # y = k*x + b 14 | k = (first[1] - last[1]) / (first[0] - last[0]) 15 | b = first[1] - k * first[0] 16 | 17 | for coordinate in coordinates: 18 | if (k * coordinate[0] + b) != coordinate[1]: 19 | return False 20 | 21 | return True 22 | -------------------------------------------------------------------------------- /may_challenge/09_valid_perfect_square.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isPerfectSquare(self, num: int) -> bool: 3 | if num in [0, 1]: 4 | return num 5 | 6 | high, low = num // 2, 0 7 | 8 | while low <= high: 9 | middle = (high + low) // 2 10 | if middle ** 2 < num: 11 | low = middle + 1 12 | elif middle ** 2 > num: 13 | high = middle - 1 14 | else: 15 | return True 16 | 17 | return False 18 | -------------------------------------------------------------------------------- /may_challenge/10_town_judge.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | class Graph: 4 | def __init__(self, vertex_count: int, edges: List[List[int]]): 5 | self.vertex_count = vertex_count 6 | self.adj_list = [set() for _ in range(vertex_count)] 7 | 8 | for edge in edges: 9 | self.adj_list[edge[0]].add(edge[1]) 10 | 11 | 12 | def find_sink_of_graph(graph: Graph) -> int: 13 | trusts_no_one = [] 14 | for i in range(graph.vertex_count): 15 | if len(graph.adj_list[i]) == 0: 16 | trusts_no_one.append(i) 17 | 18 | for i in trusts_no_one: 19 | all_trusts = True 20 | for vertex in range(graph.vertex_count): 21 | if vertex != i and i not in graph.adj_list[vertex]: 22 | all_trusts = False 23 | break 24 | if all_trusts: 25 | return i 26 | 27 | return -2 28 | 29 | 30 | class Solution: 31 | def findJudge(self, N: int, trust: List[List[int]]) -> int: 32 | for edge in trust: 33 | edge[0] -= 1 34 | edge[1] -= 1 35 | 36 | graph = Graph(N, trust) 37 | 38 | return find_sink_of_graph(graph) + 1 39 | -------------------------------------------------------------------------------- /may_challenge/11_flood_fill.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def floodFill(self, image: List[List[int]], sr: int, sc: int, newColor: int) -> List[List[int]]: 3 | visited = set() 4 | color = image[sr][sc] 5 | self.inplaceFloodFill(image, sr, sc, newColor, color, visited) 6 | 7 | return image 8 | 9 | def inplaceFloodFill( 10 | self, 11 | image: List[List[int]], 12 | sr: int, sc: int, 13 | newColor: int, 14 | color: int, 15 | visited: set 16 | ): 17 | print(sr, sc) 18 | if (sr, sc) in visited: 19 | return 20 | 21 | image[sr][sc] = newColor 22 | visited.add((sr, sc)) 23 | 24 | if sr + 1 < len(image) and image[sr+1][sc] == color: 25 | self.inplaceFloodFill(image, sr+1, sc, newColor, color, visited) 26 | 27 | if sc + 1 < len(image[0]) and image[sr][sc+1] == color: 28 | self.inplaceFloodFill(image, sr, sc+1, newColor, color, visited) 29 | 30 | if sr - 1 >= 0 and image[sr-1][sc] == color: 31 | self.inplaceFloodFill(image, sr-1, sc, newColor, color, visited) 32 | 33 | if sc - 1 >= 0 and image[sr][sc-1] == color: 34 | self.inplaceFloodFill(image, sr, sc-1, newColor, color, visited) 35 | -------------------------------------------------------------------------------- /may_challenge/12_single_in_sorted_array.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def singleNonDuplicate(self, nums: List[int]) -> int: 3 | if len(nums) == 1: 4 | return nums[0] 5 | 6 | high, low = len(nums) - 1, 0 7 | 8 | while low < high: 9 | middle = (low + high) // 2 10 | 11 | if nums[middle] not in [nums[middle-1], nums[middle+1]]: 12 | return nums[middle] 13 | 14 | count = (high - low) // 2 15 | if nums[middle] == nums[middle-1]: 16 | if count % 2 == 0: 17 | high = middle - 2 18 | else: 19 | low = middle + 1 20 | else: 21 | if count % 2 == 0: 22 | low = middle + 2 23 | else: 24 | high = middle - 1 25 | 26 | if count == 1: 27 | if nums[middle] == nums[middle-1]: 28 | return nums[middle+1] 29 | return nums[middle-1] 30 | 31 | return nums[low] 32 | -------------------------------------------------------------------------------- /may_challenge/13_remove_k_digits.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def removeKdigits(self, num: str, k: int) -> str: 3 | stack = [] 4 | for digit in num: 5 | while k > 0 and len(stack) > 0 and stack[-1] > digit: 6 | k -= 1 7 | stack.pop() 8 | stack.append(digit) 9 | 10 | if k > 0: 11 | stack = stack[:-k] 12 | 13 | return "".join(stack).lstrip("0") or "0" 14 | -------------------------------------------------------------------------------- /may_challenge/15_max_circular_subarray.py: -------------------------------------------------------------------------------- 1 | 2 | class Solution: 3 | def maxSubarraySumCircular(self, nums: List[int]) -> int: 4 | n = len(nums) 5 | if n == 1: 6 | return nums[0] 7 | 8 | sum_ = sum(nums) 9 | return max([ 10 | self.maxSub(nums), 11 | sum_ + self.maxSub([-num for num in nums[:n-1]]), 12 | sum_ + self.maxSub([-num for num in nums[1:]]), 13 | ]) 14 | 15 | def maxSub(self, nums): 16 | n = len(nums) 17 | start, end = 0, 0 18 | max_sum = current_sum = nums[0] 19 | for i in range(1, n): 20 | if current_sum + nums[i] > nums[i]: 21 | current_sum = current_sum + nums[i] 22 | end = i 23 | else: 24 | current_sum = nums[i] 25 | start = end = i 26 | 27 | if current_sum > max_sum: 28 | max_sum = current_sum 29 | 30 | return max_sum 31 | -------------------------------------------------------------------------------- /may_challenge/16_odd_even_linked_list.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 | class Solution: 9 | def oddEvenList(self, head: ListNode) -> ListNode: 10 | if not head or not head.next: 11 | return head 12 | 13 | even = ListNode(head.val) 14 | odd = ListNode(head.next.val) 15 | even_head = even 16 | odd_head = odd 17 | head = head.next.next 18 | 19 | i = 0 20 | while head: 21 | if i % 2 == 0: 22 | even.next = ListNode(head.val) 23 | even = even.next 24 | else: 25 | odd.next = ListNode(head.val) 26 | odd = odd.next 27 | 28 | head = head.next 29 | i += 1 30 | 31 | even.next = odd_head 32 | return even_head 33 | -------------------------------------------------------------------------------- /may_challenge/17_find_anagrams.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def findAnagrams(self, s: str, p: str) -> List[int]: 3 | s_len = len(s) 4 | p_len = len(p) 5 | 6 | if p_len > s_len: 7 | return [] 8 | 9 | p_counter = collections.Counter(p) 10 | s_counter = collections.Counter(s[:p_len]) 11 | result = [] 12 | 13 | if p_counter == s_counter: 14 | result.append(0) 15 | 16 | for i in range(p_len, s_len): 17 | start, end = s[i-p_len], s[i] 18 | 19 | s_counter[end] += 1 20 | s_counter[start] -= 1 21 | 22 | if not s_counter[start]: 23 | del s_counter[start] 24 | 25 | if s_counter == p_counter: 26 | result.append(i-p_len+1) 27 | 28 | return result 29 | -------------------------------------------------------------------------------- /may_challenge/18_permutation_in_string.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def checkInclusion(self, p: str, s: str) -> bool: 3 | s_len = len(s) 4 | p_len = len(p) 5 | 6 | if p_len > s_len: 7 | return False 8 | 9 | p_counter = collections.Counter(p) 10 | s_counter = collections.Counter(s[:p_len]) 11 | 12 | if p_counter == s_counter: 13 | return True 14 | 15 | for i in range(p_len, s_len): 16 | start, end = s[i-p_len], s[i] 17 | 18 | s_counter[end] += 1 19 | s_counter[start] -= 1 20 | 21 | if not s_counter[start]: 22 | del s_counter[start] 23 | 24 | if s_counter == p_counter: 25 | return True 26 | 27 | return False 28 | -------------------------------------------------------------------------------- /may_challenge/19_online_stock_span.py: -------------------------------------------------------------------------------- 1 | class StockSpanner: 2 | 3 | def __init__(self): 4 | self.prices = [] 5 | 6 | def next(self, price: int) -> int: 7 | ans = 1 8 | while self.prices and price >= self.prices[-1][0]: 9 | _, count = self.prices.pop() 10 | ans += count 11 | 12 | self.prices.append([price, ans]) 13 | 14 | return ans 15 | -------------------------------------------------------------------------------- /may_challenge/20_kth_smallest_in_bst.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def kthSmallest(self, root: TreeNode, k: int) -> int: 3 | current = root 4 | stack = [] 5 | 6 | i = 0 7 | while True: 8 | if current: 9 | stack.append(current) 10 | current = current.left 11 | continue 12 | 13 | if stack: 14 | current = stack.pop() 15 | i += 1 16 | if i == k: 17 | return current.val 18 | 19 | current = current.right 20 | continue 21 | 22 | break 23 | -------------------------------------------------------------------------------- /may_challenge/21_count_squares.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def countSquares(self, matrix: List[List[int]]) -> int: 3 | if not matrix: 4 | return 0 5 | 6 | result = 0 7 | rows = len(matrix) 8 | cols = len(matrix[0]) 9 | 10 | for i in range(rows): 11 | for j in range(cols): 12 | if matrix[i][j] == 1: 13 | if i == 0 or j == 0: 14 | result += 1 15 | else: 16 | val = matrix[i][j] + min( 17 | matrix[i-1][j-1], 18 | matrix[i][j-1], 19 | matrix[i-1][j] 20 | ) 21 | result += val 22 | matrix[i][j] = val 23 | return result 24 | -------------------------------------------------------------------------------- /may_challenge/22_sort_chars_by_frequency.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | 3 | 4 | class Solution: 5 | def frequencySort(self, s: str) -> str: 6 | result = '' 7 | counter = Counter(s) 8 | 9 | for char in sorted(counter, key=lambda k: -counter[k]): 10 | result += char * counter[char] 11 | 12 | return result 13 | -------------------------------------------------------------------------------- /may_challenge/23_interval_intersection.py: -------------------------------------------------------------------------------- 1 | 2 | class Solution: 3 | def intervalIntersection(self, A: List[List[int]], B: List[List[int]]) -> List[List[int]]: 4 | if not A or not B: 5 | return [] 6 | 7 | result = [] 8 | i, j = 0, 0 9 | 10 | while i < len(A) and j < len(B): 11 | start = max(A[i][0], B[j][0]) 12 | if A[i][1] < B[j][1]: 13 | if start <= A[i][1]: 14 | result.append([start, A[i][1]]) 15 | i += 1 16 | elif A[i][1] > B[j][1]: 17 | if start <= B[j][1]: 18 | result.append([start, B[j][1]]) 19 | j += 1 20 | else: 21 | result.append([start, A[i][1]]) 22 | i += 1 23 | j += 1 24 | 25 | return result 26 | -------------------------------------------------------------------------------- /may_challenge/24_bst_from_preorder.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | class TreeNode: 3 | def __init__(self, val=0, left=None, right=None): 4 | self.val = val 5 | self.left = left 6 | self.right = right 7 | 8 | 9 | class Solution: 10 | def bstFromPreorder(self, preorder: List[int]) -> TreeNode: 11 | if not preorder: 12 | return None 13 | 14 | val = preorder[0] 15 | root = TreeNode(val) 16 | root.left = self.bstFromPreorder([n for n in preorder if n < val]) 17 | root.right = self.bstFromPreorder([n for n in preorder if n > val]) 18 | 19 | return root 20 | -------------------------------------------------------------------------------- /may_challenge/25_uncrossed_lines.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def maxUncrossedLines(self, A: List[int], B: List[int]) -> int: 3 | m, n = len(A), len(B) 4 | dp = [[0 for _ in range(n+1)] for i in range(m+1)] 5 | 6 | for i in range(m): 7 | for j in range(n): 8 | if A[i] == B[j]: 9 | dp[i+1][j+1] = dp[i][j] + 1 10 | else: 11 | dp[i+1][j+1] = max(dp[i+1][j], dp[i][j+1]) 12 | 13 | return dp[m][n] 14 | -------------------------------------------------------------------------------- /may_challenge/26_contiguous_array.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def findMaxLength(self, nums: List[int]) -> int: 3 | max_contiguous = 0 4 | first_occurances = {0: -1} 5 | sum_ = 0 6 | 7 | for i, num in enumerate(nums): 8 | if num == 0: 9 | sum_ -= 1 10 | else: 11 | sum_ += 1 12 | 13 | if sum_ not in first_occurances: 14 | first_occurances[sum_] = i 15 | continue 16 | 17 | max_contiguous = max(i - first_occurances[sum_], max_contiguous) 18 | 19 | return max_contiguous 20 | -------------------------------------------------------------------------------- /may_challenge/28_count_bits.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def countBits(self, num: int) -> List[int]: 3 | result = [] 4 | 5 | for i in range(num+1): 6 | result.append(bin(i).count('1')) 7 | 8 | return result 9 | -------------------------------------------------------------------------------- /may_challenge/29_course_schedule.py: -------------------------------------------------------------------------------- 1 | class Graph: 2 | def __init__(self, size) -> None: 3 | self.size = size 4 | self._graph = collections.defaultdict(list) 5 | 6 | def addEdge(self, course: int, requirement: int) -> None: 7 | self._graph[course].append(requirement) 8 | 9 | def hasCycle(self) -> bool: 10 | rec_stack = set() 11 | visited = set() 12 | 13 | for vertex in range(self.size): 14 | if vertex in visited: 15 | continue 16 | 17 | if self._isCyclic(vertex, rec_stack, visited): 18 | return True 19 | 20 | return False 21 | 22 | def _isCyclic(self, vertex, rec_stack, visited): 23 | rec_stack.add(vertex) 24 | visited.add(vertex) 25 | 26 | for requirement in self._graph[vertex]: 27 | if requirement not in visited: 28 | if self._isCyclic(requirement, rec_stack, visited): 29 | return True 30 | elif requirement in rec_stack: 31 | return True 32 | 33 | rec_stack.remove(vertex) 34 | return False 35 | 36 | 37 | class Solution: 38 | def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool: 39 | graph = Graph(numCourses) 40 | 41 | for course, requirement in prerequisites: 42 | graph.addEdge(course, requirement) 43 | 44 | return not graph.hasCycle() 45 | -------------------------------------------------------------------------------- /may_challenge/30_k_closest_to_origin.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def kClosest(self, points: List[List[int]], K: int) -> List[List[int]]: 3 | heap = [] 4 | 5 | for point in points: 6 | distance_squared = point[0]**2 + point[1]**2 7 | heapq.heappush(heap, (distance_squared, point)) 8 | 9 | k_closest = heapq.nsmallest(K, heap) 10 | 11 | return [point for _, point in k_closest] 12 | -------------------------------------------------------------------------------- /may_challenge/31_edit_distance.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def minDistance(self, word1: str, word2: str) -> int: 3 | n, m = len(word1), len(word2) 4 | dp = [[0 for _ in range(m+1)] for _ in range(n+1)] 5 | 6 | for i in range(1, n+1): 7 | dp[i][0] = i 8 | 9 | for j in range(1, m+1): 10 | dp[0][j] = j 11 | 12 | for i in range(1, n+1): 13 | for j in range(1, m+1): 14 | if word1[i-1] == word2[j-1]: 15 | dp[i][j] = dp[i-1][j-1] 16 | else: 17 | dp[i][j] = 1 + min( 18 | dp[i-1][j], 19 | dp[i][j-1], 20 | dp[i-1][j-1], 21 | ) 22 | 23 | return dp[n][m] 24 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | ## Leetcode Solutions 2 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/1_array/best_time_to_buy_and_sell_stock_ii/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println(maxProfit([]int{1, 2, 3, 4, 5})) // expected 4 7 | } 8 | 9 | func maxProfit(prices []int) int { 10 | if len(prices) == 0 { 11 | return 0 12 | } 13 | 14 | minPrice, maxPrice := prices[0], prices[0] 15 | totalGain, currentGain := 0, 0 16 | 17 | for _, price := range prices[1:] { 18 | if price < maxPrice { 19 | currentGain = maxPrice - minPrice 20 | totalGain += currentGain 21 | minPrice = price 22 | } 23 | maxPrice = price 24 | } 25 | 26 | currentGain = maxPrice - minPrice 27 | totalGain += currentGain 28 | 29 | return totalGain 30 | } 31 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/1_array/best_time_to_buy_and_sell_stock_ii/solution.py: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/ 2 | 3 | 4 | class Solution: 5 | def maxProfit(self, prices): 6 | if not prices: 7 | return 0 8 | 9 | max_val = min_val = prices[0] 10 | total_gain = current_gain = 0 11 | 12 | for index in range(1, len(prices)): 13 | if prices[index] < max_val: 14 | current_gain = max_val - min_val 15 | total_gain += current_gain 16 | min_val = prices[index] 17 | 18 | max_val = prices[index] 19 | 20 | current_gain = max_val - min_val 21 | total_gain += current_gain 22 | 23 | return total_gain 24 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/1_array/contains_duplicate/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println(containsDuplicate([]int{1, 2, 3, 1})) // expected true 7 | fmt.Println(containsDuplicate([]int{1, 2, 3, 4})) // expected false 8 | } 9 | 10 | func containsDuplicate(nums []int) bool { 11 | seen := make(map[int]bool) 12 | 13 | for _, num := range nums { 14 | if seen[num] { 15 | return true 16 | } 17 | seen[num] = true 18 | } 19 | 20 | return false 21 | } 22 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/1_array/contains_duplicate/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def containsDuplicate(self, nums: List[int]) -> bool: 6 | seen = set() 7 | 8 | for num in nums: 9 | if num in seen: 10 | return True 11 | seen.add(num) 12 | 13 | return False 14 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/1_array/intersection_of_two_arrays_ii/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | fmt.Println(intersect([]int{1, 2, 2, 1}, []int{2, 2})) // expected []int{2, 2} 9 | } 10 | 11 | func intersect(nums1 []int, nums2 []int) []int { 12 | var result []int 13 | counter1 := counter(nums1) 14 | counter2 := counter(nums2) 15 | 16 | for num, count := range counter1 { 17 | minCount := min(count, counter2[num]) 18 | for i := 0; i < minCount; i++ { 19 | result = append(result, num) 20 | } 21 | } 22 | 23 | return result 24 | } 25 | 26 | func counter(nums []int) map[int]int { 27 | c := make(map[int]int) 28 | 29 | for _, num := range nums { 30 | c[num]++ 31 | } 32 | 33 | return c 34 | } 35 | 36 | func min(a, b int) int { 37 | if a < b { 38 | return a 39 | } 40 | return b 41 | } 42 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/1_array/intersection_of_two_arrays_ii/solution.py: -------------------------------------------------------------------------------- 1 | import collections 2 | from typing import List 3 | 4 | 5 | class Solution: 6 | def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]: 7 | nums1_counter = collections.Counter(nums1) 8 | nums2_counter = collections.Counter(nums2) 9 | 10 | result = [] 11 | for num in nums1_counter: 12 | if num in nums2_counter: 13 | min_count = min(nums1_counter[num], nums2_counter[num]) 14 | result.extend([num]*min_count) 15 | 16 | return result 17 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/1_array/move_zeroes/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | nums := []int{0, 1, 0, 3, 12} 7 | moveZeroes(nums) 8 | fmt.Println(nums) // expected []int{1, 3, 12, 0, 0} 9 | } 10 | 11 | func moveZeroes(nums []int) { 12 | zeroIndex := -1 13 | 14 | for i, num := range nums { 15 | if num == 0 && zeroIndex == -1 { 16 | zeroIndex = i 17 | } 18 | if num != 0 && zeroIndex != -1 { 19 | nums[zeroIndex] = num 20 | nums[i] = 0 21 | zeroIndex++ 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/1_array/move_zeroes/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def moveZeroes(self, nums: List[int]) -> None: 6 | for index in range(len(nums)-1, -1, -1): 7 | if nums[index] == 0: 8 | del nums[index] 9 | nums.append(0) 10 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/1_array/plus_one/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println(plusOne([]int{1, 9, 9, 9})) // expected []int{2, 0, 0, 0} 7 | } 8 | 9 | func plusOne(digits []int) []int { 10 | for i := len(digits) - 1; i >= 0; i-- { 11 | if digits[i] == 9 { 12 | digits[i] = 0 13 | } else { 14 | digits[i] = digits[i] + 1 15 | break 16 | } 17 | } 18 | 19 | if digits[0] == 0 { 20 | digits = append([]int{1}, digits...) 21 | } 22 | 23 | return digits 24 | } 25 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/1_array/plus_one/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def plusOne(self, digits: List[int]) -> List[int]: 6 | length = len(digits) 7 | 8 | for i in range(length - 1, -1, -1): 9 | digit = digits[i] 10 | 11 | if digit == 9: 12 | digits[i] = 0 13 | else: 14 | digits[i] += 1 15 | break 16 | 17 | if digits[0] == 0: 18 | digits = [1] + digits 19 | 20 | return digits 21 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/1_array/remove_duplicates_from_sorted_array/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | nums := []int{1, 1, 2, 3, 3, 4, 4} 7 | fmt.Println(removeDuplicates(nums)) 8 | fmt.Println(nums) 9 | } 10 | 11 | func removeDuplicates(nums []int) int { 12 | prev := 0 13 | n := 0 14 | 15 | for i, num := range nums { 16 | if i == 0 || num != prev { 17 | nums[n] = num 18 | n += 1 19 | } 20 | prev = num 21 | } 22 | 23 | return n 24 | } 25 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/1_array/remove_duplicates_from_sorted_array/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def removeDuplicates(self, numbers: List[int]): 6 | previous = float('-inf') 7 | index = len(numbers) - 1 8 | 9 | for number in reversed(numbers): 10 | if number == previous: 11 | del numbers[index] 12 | previous = number 13 | index -= 1 14 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/1_array/rotate_array/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | nums := []int{1, 2, 3, 4, 5, 6, 7} 7 | rotate(nums, 3) 8 | fmt.Println(nums) // expected [5,6,7,1,2,3,4] 9 | } 10 | 11 | func rotate(nums []int, k int) { 12 | length := len(nums) 13 | k = k % length 14 | rotated := nums[length-k:] 15 | 16 | rotated = append(rotated, nums[:length-k]...) 17 | 18 | for i := 0; i < length; i++ { 19 | nums[i] = rotated[i] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/1_array/rotate_array/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def rotate(self, nums: List[int], k: int) -> None: 6 | length = len(nums) 7 | k = k % length 8 | 9 | nums_rotated = nums[length - k:] + nums[:length - k] 10 | 11 | for i in range(length): 12 | nums[i] = nums_rotated[i] 13 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/1_array/rotate_image/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | image := [][]int{ 7 | {1, 2, 3, 4}, 8 | {5, 6, 7, 8}, 9 | {9, 10, 11, 12}, 10 | {13, 14, 15, 16}, 11 | } 12 | rotate(image) 13 | fmt.Println(image) 14 | } 15 | 16 | func rotate(matrix [][]int) { 17 | size := len(matrix) 18 | matrixCopy := make([][]int, size) 19 | copy2d(matrixCopy, matrix) 20 | 21 | for i := 0; i < size; i++ { 22 | for j := 0; j < size; j++ { 23 | matrix[j][size-i-1] = matrixCopy[i][j] 24 | } 25 | } 26 | } 27 | 28 | func copy2d(dst, src [][]int) { 29 | for i := range src { 30 | dst[i] = make([]int, len(src[i])) 31 | copy(dst[i], src[i]) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/1_array/rotate_image/solution.py: -------------------------------------------------------------------------------- 1 | from copy import deepcopy 2 | from typing import List 3 | 4 | 5 | class Solution: 6 | def rotate(self, matrix: List[List[int]]) -> None: 7 | size = len(matrix) 8 | matrix_copy = deepcopy(matrix) 9 | 10 | for i in range(size): 11 | for j in range(size): 12 | matrix[j][size-i-1] = matrix_copy[i][j] 13 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/1_array/single_number/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println(singleNumber([]int{1, 2, 2, 3})) // expected 2 7 | fmt.Println(singleNumber([]int{2, 3, 4, 5, 5})) // expected 5 8 | } 9 | 10 | func singleNumber(nums []int) int { 11 | xorSum := 0 12 | 13 | for _, num := range nums { 14 | xorSum ^= num 15 | } 16 | 17 | return xorSum 18 | } 19 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/1_array/single_number/solution.py: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/problems/single-number/submissions/ 2 | 3 | 4 | def single_number(nums): 5 | xor_sum = 0 6 | 7 | for num in nums: 8 | xor_sum = xor_sum ^ num 9 | 10 | return xor_sum 11 | 12 | 13 | if __name__ == '__main__': 14 | cases = [ 15 | ([2, 2, 1], 1), 16 | ([4, 1, 2, 1, 2], 4) 17 | ] 18 | 19 | for case in cases: 20 | assert single_number(case[0]) == case[1] 21 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/1_array/two_sum/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println(twoSum([]int{2, 7, 11, 15}, 9)) // expected []int{0, 1} 7 | } 8 | 9 | func twoSum(nums []int, target int) []int { 10 | complements := make(map[int]int) 11 | 12 | for i, num := range nums { 13 | complements[target-num] = i 14 | } 15 | 16 | for j, num := range nums { 17 | i, exists := complements[num] 18 | 19 | if !exists { 20 | continue 21 | } 22 | 23 | if i != j { 24 | return []int{i, j} 25 | } 26 | } 27 | 28 | return []int{-1, -1} 29 | } 30 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/1_array/two_sum/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def twoSum(self, numbers, target): 3 | complements = {} 4 | 5 | for index, number in enumerate(numbers): 6 | complements[target - number] = index 7 | 8 | for index, number in enumerate(numbers): 9 | if number in complements and complements[number] != index: 10 | return [index, complements[number]] 11 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/2_strings/count_and_say/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | func main() { 9 | fmt.Println("result", countAndSay("11")) 10 | fmt.Println("result", countAndSay("21")) 11 | } 12 | 13 | func countAndSay(num string) string { 14 | say := "" 15 | count := 1 16 | prev := int32(num[0]) 17 | 18 | for _, digit := range num[1:] { 19 | if digit == prev { 20 | count += 1 21 | continue 22 | } 23 | say += strconv.Itoa(count) + string(prev) 24 | prev = digit 25 | count = 1 26 | } 27 | 28 | return say + strconv.Itoa(count) + string(prev) 29 | } 30 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/2_strings/count_and_say/solution.py: -------------------------------------------------------------------------------- 1 | def count_and_say(num): 2 | say = "" 3 | count = 1 4 | prev = num[0] 5 | 6 | for digit in num[1:]: 7 | if digit == prev: 8 | count += 1 9 | continue 10 | say += str(count) + prev 11 | prev = digit 12 | count = 1 13 | 14 | return say + str(count) + prev 15 | 16 | 17 | if __name__ == '__main__': 18 | cases = [ 19 | ["1", "11"], 20 | ["11", "21"], 21 | ["21", "1211"], 22 | ["1211", "111221"], 23 | ["111221", "312211"] 24 | ] 25 | 26 | for case in cases: 27 | assert count_and_say(case[0]) == case[1] 28 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/2_strings/first_unique_character_in_string/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println(firstUniqChar("Azimjon")) // expected 0 7 | } 8 | 9 | func firstUniqChar(s string) int { 10 | hashMap := make(map[rune]int) 11 | 12 | for _, char := range s { 13 | hashMap[char] += 1 14 | } 15 | 16 | for i, char := range s { 17 | count, _ := hashMap[char] 18 | if count == 1 { 19 | return i 20 | } 21 | } 22 | 23 | return -1 24 | } 25 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/2_strings/first_unique_character_in_string/solution.py: -------------------------------------------------------------------------------- 1 | import collections 2 | 3 | 4 | class Solution: 5 | def firstUniqChar(self, s: str) -> int: 6 | counter = collections.Counter(s) 7 | 8 | for index, char in enumerate(s): 9 | if counter[char] == 1: 10 | return index 11 | 12 | return -1 13 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/2_strings/implement_strStr/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println(strStr("Don't Panic", "Pan")) 7 | fmt.Println(strStr("Facebook", "book")) 8 | } 9 | 10 | func strStr(haystack string, needle string) int { 11 | needleLength := len(needle) 12 | 13 | for i := 0; i <= len(haystack)-needleLength; i++ { 14 | if haystack[i:needleLength+i] == needle { 15 | return i 16 | } 17 | } 18 | 19 | return -1 20 | } 21 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/2_strings/implement_strStr/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def strStr(self, haystack: str, needle: str) -> int: 3 | return haystack.find(needle) 4 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/2_strings/longest_common_prefix/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | func main() { 9 | fmt.Println(longestCommonPrefix([]string{ 10 | "a", 11 | })) 12 | } 13 | 14 | func longestCommonPrefix(strs []string) string { 15 | if len(strs) == 0 { 16 | return "" 17 | } 18 | 19 | if len(strs[0]) == 0 { 20 | return "" 21 | } 22 | 23 | minStringLength := getMinStrLength(strs) 24 | lastPrefixIndex := getLastPrefixIndex(minStringLength, strs) 25 | 26 | return strs[0][:lastPrefixIndex] 27 | } 28 | 29 | func getLastPrefixIndex(minStringLength int, strs []string) int { 30 | for i := 0; i < minStringLength; i++ { 31 | char := strs[0][i] 32 | for _, str := range strs { 33 | if str[i] != char { 34 | return i 35 | } 36 | } 37 | } 38 | return minStringLength 39 | } 40 | 41 | func getMinStrLength(strs []string) int { 42 | minStringLength := math.MaxInt32 43 | for _, str := range strs { 44 | length := len(str) 45 | if length < minStringLength { 46 | minStringLength = length 47 | } 48 | } 49 | return minStringLength 50 | } 51 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/2_strings/longest_common_prefix/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def longestCommonPrefix(self, strs: List[str]) -> str: 6 | if not strs: 7 | return "" 8 | 9 | min_leght_str = min(strs, key=lambda s: len(s)) 10 | prefix_index = 0 11 | 12 | for i in range(len(min_leght_str)): 13 | ith_letters = [string[i] for string in strs] 14 | 15 | if len(set(ith_letters)) != 1: 16 | break 17 | 18 | prefix_index += 1 19 | 20 | return min_leght_str[:prefix_index] 21 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/2_strings/reverse_integer/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | func main() { 9 | fmt.Println(reverse(120)) // expected 21 10 | fmt.Println(reverse(712)) // expected 217 11 | } 12 | 13 | func reverse(x int) int { 14 | var digit int 15 | y := 0 16 | 17 | if x < math.MinInt32 || x > math.MaxInt32 { 18 | return 0 19 | } 20 | 21 | for x != 0 { 22 | digit = x % 10 23 | x = x / 10 24 | y *= 10 25 | y += digit 26 | } 27 | 28 | return y 29 | } 30 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/2_strings/reverse_integer/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def reverse(self, x: int) -> int: 3 | number = int(str(x).strip('-')[::-1]) * (-1 if x < 0 else 1) 4 | if number > 2 ** 31 or number < -(2 ** 31) - 1: 5 | return 0 6 | 7 | return number 8 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/2_strings/reverse_string/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | bytes := []byte("Hello") 7 | reverseString(bytes) 8 | fmt.Println(string(bytes)) 9 | } 10 | 11 | func reverseString(s []byte) { 12 | length := len(s) 13 | 14 | for i := 0; i < length/2; i++ { 15 | s[i], s[length-i-1] = s[length-i-1], s[i] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/2_strings/reverse_string/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def reverseString(self, s: List[str]) -> None: 6 | length = len(s) 7 | 8 | for i in range(length // 2): 9 | s[i], s[length - i - 1] = s[length - i - 1], s[i] 10 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/2_strings/string_to_integer/solution.py: -------------------------------------------------------------------------------- 1 | MAX_INT = 2147483647 2 | MIN_INT = -2147483648 3 | 4 | 5 | class Solution: 6 | def myAtoi(self, string: str) -> int: 7 | string = string.strip() 8 | 9 | if not string: 10 | return 0 11 | 12 | if not (string[0] in ('-', '+') or string[0].isdigit()): 13 | return 0 14 | 15 | digit_end_position = 1 16 | for index, char in enumerate(string[1:], 2): 17 | if not char.isdigit(): 18 | break 19 | 20 | digit_end_position = index 21 | 22 | try: 23 | result = int(string[:digit_end_position]) 24 | except ValueError: 25 | result = 0 26 | 27 | if result > MAX_INT: 28 | return MAX_INT 29 | 30 | if result < MIN_INT: 31 | return MIN_INT 32 | 33 | return result 34 | 35 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/2_strings/valid_anagram/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println(isAnagram("nagaram", "anagram")) 7 | fmt.Println(isAnagram("rat", "car")) 8 | } 9 | 10 | func isAnagram(s, t string) bool { 11 | if len(s) != len(t) { 12 | return false 13 | } 14 | 15 | c1 := counter(s) 16 | c2 := counter(t) 17 | 18 | if len(c1) != len(c2) { 19 | return false 20 | } 21 | 22 | for k := range c1 { 23 | v1, v2 := c1[k], c2[k] 24 | if v1 != v2 { 25 | return false 26 | } 27 | } 28 | 29 | return true 30 | } 31 | 32 | func counter(s string) map[rune]int { 33 | c := make(map[rune]int) 34 | 35 | for _, char := range s { 36 | c[char]++ 37 | } 38 | 39 | return c 40 | } 41 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/2_strings/valid_anagram/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isAnagram(self, s: str, t: str) -> bool: 3 | counter_s = self.countChars(s) 4 | counter_t = self.countChars(t) 5 | 6 | return counter_s == counter_t 7 | 8 | def countChars(self, s): 9 | counter = {} 10 | 11 | for char in s: 12 | if char in counter: 13 | counter[char] += 1 14 | else: 15 | counter[char] = 1 16 | 17 | return counter 18 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/2_strings/valid_palindrome/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | const ( 9 | Uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 10 | Lowercase = "abcdefghijklmnopqrstuvwxyz" 11 | Alphabetic = Uppercase + Lowercase 12 | Numeric = "0123456789" 13 | Alphanumeric = Alphabetic + Numeric 14 | ) 15 | 16 | func main() { 17 | fmt.Println(isPalindrome("flool")) 18 | } 19 | 20 | func isPalindrome(s string) bool { 21 | s = strings.ToLower(s) 22 | clean := "" 23 | 24 | // better: regex, _ := regexp.Compile("[A-Z0-9]+") 25 | for _, c := range s { 26 | if strings.Contains(Alphanumeric, string(c)) { 27 | clean += string(c) 28 | } 29 | } 30 | 31 | length := len(clean) 32 | 33 | for i := 0; i < length/2; i++ { 34 | if clean[i] != clean[length-i-1] { 35 | return false 36 | } 37 | } 38 | 39 | return true 40 | } 41 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/2_strings/valid_palindrome/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isPalindrome(self, s: str) -> bool: 3 | s = s.lower() 4 | clean = '' 5 | 6 | for c in s: 7 | if c.isalnum(): 8 | clean += c 9 | 10 | return clean == clean[::-1] 11 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/3_linked_list/delete_node_in_linked_list/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | ll := &ListNode{ 7 | Val: 1, 8 | Next: &ListNode{ 9 | Val: 2, 10 | Next: &ListNode{ 11 | Val: 3, 12 | Next: nil, 13 | }, 14 | }, 15 | } 16 | deleteNode(ll) // deletes 1 17 | fmt.Println(ll.Val) // expected 2 18 | fmt.Println(ll.Next.Val) // expected 3 19 | } 20 | 21 | type ListNode struct { 22 | Val int 23 | Next *ListNode 24 | } 25 | 26 | func deleteNode(node *ListNode) { 27 | node.Val = node.Next.Val 28 | node.Next = node.Next.Next 29 | } 30 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/3_linked_list/delete_node_in_linked_list/solution.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 | class Solution: 8 | def deleteNode(self, node): 9 | """ 10 | :type node: ListNode 11 | :rtype: void Do not return anything, modify node in-place instead. 12 | """ 13 | node.val = node.next.val 14 | node.next = node.next.next 15 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/3_linked_list/linked_list_cycle/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | ll := &ListNode{ 7 | Val: 1, 8 | Next: &ListNode{ 9 | Val: 2, 10 | Next: nil, 11 | }, 12 | } 13 | fmt.Println(hasCycle(ll)) // expected false 14 | ll.Next.Next = ll 15 | fmt.Println(hasCycle(ll)) // expected true 16 | } 17 | 18 | type ListNode struct { 19 | Val int 20 | Next *ListNode 21 | } 22 | 23 | // uses extra O(n) space 24 | func _hasCycle(head *ListNode) bool { 25 | visited := make(map[*ListNode]bool) 26 | var exists bool 27 | 28 | for head != nil { 29 | _, exists = visited[head] 30 | if exists { 31 | return true 32 | } 33 | visited[head] = true 34 | head = head.Next 35 | } 36 | 37 | return false 38 | } 39 | 40 | // with O(1) space + 2 times faster 41 | func hasCycle(head *ListNode) bool { 42 | if head == nil { 43 | return false 44 | } 45 | 46 | slow := head 47 | fast := head.Next 48 | 49 | for slow != nil && fast != nil && fast.Next != nil { 50 | if slow == fast { 51 | return true 52 | } 53 | slow = slow.Next 54 | fast = fast.Next.Next 55 | } 56 | 57 | return false 58 | } 59 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/3_linked_list/linked_list_cycle/solution.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azimjohn/leetcode/463d9bdf53bfb6f10f1e5c8b233a28107351b82e/top_interview_questions/1_easy/3_linked_list/linked_list_cycle/solution.py -------------------------------------------------------------------------------- /top_interview_questions/1_easy/3_linked_list/merge_two_sorted_lists/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | l1 := &ListNode{ 7 | Val: 2, 8 | Next: &ListNode{ 9 | Val: 3, 10 | }, 11 | } 12 | l2 := &ListNode{ 13 | Val: 1, 14 | Next: &ListNode{ 15 | Val: 4, 16 | }, 17 | } 18 | merged := mergeTwoLists(l1, l2) 19 | for merged != nil { 20 | fmt.Print(merged.Val, " ") 21 | merged = merged.Next 22 | } 23 | } 24 | 25 | type ListNode struct { 26 | Val int 27 | Next *ListNode 28 | } 29 | 30 | func mergeTwoLists(l1 *ListNode, l2 *ListNode) *ListNode { 31 | mergedHead := &ListNode{Val: 0} 32 | current := mergedHead 33 | 34 | for l1 != nil && l2 != nil { 35 | if l1.Val < l2.Val { 36 | current.Next = &ListNode{Val: l1.Val} 37 | l1 = l1.Next 38 | } else { 39 | current.Next = &ListNode{Val: l2.Val} 40 | l2 = l2.Next 41 | } 42 | current = current.Next 43 | } 44 | 45 | if l1 != nil { 46 | current.Next = l1 47 | } 48 | if l2 != nil { 49 | current.Next = l2 50 | } 51 | 52 | return mergedHead.Next 53 | } 54 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/3_linked_list/merge_two_sorted_lists/solution.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 | class Solution: 9 | def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode: 10 | new_node = curr = ListNode(0) 11 | 12 | while l1 and l2: 13 | if l1.val <= l2.val: 14 | curr.next = ListNode(l1.val) 15 | l1 = l1.next 16 | else: 17 | curr.next = ListNode(l2.val) 18 | l2 = l2.next 19 | curr = curr.next 20 | 21 | curr.next = l1 or l2 22 | 23 | return new_node.next 24 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/3_linked_list/palindrome_linked_list/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | l1 := &ListNode{ 7 | Val: 1, 8 | Next: &ListNode{ 9 | Val: 2, 10 | Next: &ListNode{ 11 | Val: 3, 12 | }, 13 | }, 14 | } 15 | l2 := &ListNode{ 16 | Val: 1, 17 | Next: &ListNode{ 18 | Val: 2, 19 | Next: &ListNode{ 20 | Val: 1, 21 | }, 22 | }, 23 | } 24 | fmt.Println(isPalindrome(l1)) // expected false 25 | fmt.Println(isPalindrome(l2)) // expected true 26 | } 27 | 28 | type stack []int 29 | 30 | func (s stack) Push(v int) stack { 31 | return append(s, v) 32 | } 33 | 34 | func (s stack) Pop() (stack, int) { 35 | l := len(s) 36 | return s[:l-1], s[l-1] 37 | } 38 | 39 | type ListNode struct { 40 | Val int 41 | Next *ListNode 42 | } 43 | 44 | func isPalindrome(head *ListNode) bool { 45 | s := stack{} 46 | curr := head 47 | var val int 48 | 49 | for curr != nil { 50 | s = s.Push(curr.Val) 51 | curr = curr.Next 52 | } 53 | 54 | curr = head 55 | for curr != nil { 56 | s, val = s.Pop() 57 | if val != curr.Val { 58 | return false 59 | } 60 | curr = curr.Next 61 | } 62 | 63 | return true 64 | } 65 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/3_linked_list/palindrome_linked_list/solution.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 | # TODO: improve 9 | class Solution: 10 | def isPalindrome(self, head: ListNode) -> bool: 11 | array_list = [] 12 | 13 | while head: 14 | array_list.append(head.val) 15 | head = head.next 16 | 17 | return array_list == array_list[::-1] 18 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/3_linked_list/remove_nth_node_from_end_of_list/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type ListNode struct { 4 | Val int 5 | Next *ListNode 6 | } 7 | 8 | func removeNthFromEnd(head *ListNode, n int) *ListNode { 9 | length := getLength(head) 10 | 11 | if n == 1 && length == 1 { 12 | return nil 13 | } 14 | 15 | return removeNthElement(head, length-n) 16 | } 17 | 18 | func removeNthElement(head *ListNode, n int) *ListNode { 19 | node := head 20 | 21 | for i := 0; i < n-1; i++ { 22 | node = node.Next 23 | } 24 | 25 | if node.Next != nil { 26 | if n == 0 { 27 | node.Val = node.Next.Val 28 | } 29 | node.Next = node.Next.Next 30 | } 31 | 32 | return head 33 | } 34 | 35 | func getLength(head *ListNode) int { 36 | i := 0 37 | 38 | for head != nil { 39 | head = head.Next 40 | i++ 41 | } 42 | 43 | return i 44 | } 45 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/3_linked_list/remove_nth_node_from_end_of_list/solution.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 | class Solution: 8 | def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: 9 | length = self.getLength(head) 10 | 11 | if n == 1 and length == 1: 12 | return None 13 | 14 | return self.removeNthElement(head, length - n) 15 | 16 | def removeNthElement(self, head: ListNode, n: int) -> ListNode: 17 | node = head 18 | for _ in range(n - 1): 19 | node = node.next 20 | 21 | if node.next: 22 | if n == 0: 23 | node.val = node.next.val 24 | node.next = node.next.next 25 | 26 | return head 27 | 28 | def getLength(self, head: ListNode) -> int: 29 | if not head: 30 | return 0 31 | 32 | return self.getLength(head.next) + 1 -------------------------------------------------------------------------------- /top_interview_questions/1_easy/3_linked_list/reverse_linked_list/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | ll := &ListNode{ 7 | Val: 1, 8 | Next: &ListNode{ 9 | Val: 2, 10 | Next: &ListNode{ 11 | Val: 3, 12 | }, 13 | }, 14 | } 15 | ll = reverseList(ll) 16 | for ll != nil { 17 | fmt.Print(ll.Val, " ") 18 | ll = ll.Next 19 | } // expected 3 2 1 20 | } 21 | 22 | type ListNode struct { 23 | Val int 24 | Next *ListNode 25 | } 26 | 27 | func reverseList(head *ListNode) *ListNode { 28 | var prev *ListNode 29 | var next *ListNode 30 | 31 | for head != nil { 32 | next = head.Next 33 | head.Next = prev 34 | prev = head 35 | head = next 36 | } 37 | 38 | return prev 39 | } 40 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/3_linked_list/reverse_linked_list/solution.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 | # TODO: improve 9 | class Solution: 10 | def reverseList(self, head: ListNode) -> ListNode: 11 | list_vals = [] 12 | while head: 13 | list_vals.append(head.val) 14 | head = head.next 15 | 16 | list_vals = list_vals[::-1] 17 | reversed_list = ListNode(list_vals[0]) 18 | reversed_list_head = reversed_list 19 | 20 | for val in list_vals[1:]: 21 | reversed_list.next = ListNode(val) 22 | reversed_list = reversed_list.next 23 | 24 | return reversed_list_head 25 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/4_trees/binary_tree_lever_order_traversal/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | tree := &TreeNode{ 7 | Val: 2, 8 | Left: &TreeNode{ 9 | Val: 1, 10 | }, 11 | Right: &TreeNode{ 12 | Val: 3, 13 | }, 14 | } 15 | fmt.Println(levelOrder(tree)) 16 | } 17 | 18 | type TreeNode struct { 19 | Val int 20 | Left *TreeNode 21 | Right *TreeNode 22 | } 23 | 24 | func levelOrder(root *TreeNode) [][]int { 25 | depth := maxDepth(root) 26 | levels := make([][]int, depth) 27 | fmt.Println(levels) 28 | helper(root, 0, levels) 29 | 30 | return levels 31 | } 32 | 33 | func helper(root *TreeNode, level int, levels [][]int) { 34 | if root == nil || level == len(levels) { 35 | return 36 | } 37 | 38 | levels[level] = append(levels[level], root.Val) 39 | helper(root.Left, level+1, levels) 40 | helper(root.Right, level+1, levels) 41 | } 42 | 43 | func maxDepth(root *TreeNode) int { 44 | if root == nil { 45 | return 0 46 | } 47 | 48 | leftMaxDepth := maxDepth(root.Left) 49 | rightMaxDepth := maxDepth(root.Right) 50 | 51 | if leftMaxDepth > rightMaxDepth { 52 | return leftMaxDepth + 1 53 | } 54 | 55 | return rightMaxDepth + 1 56 | } 57 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/4_trees/binary_tree_lever_order_traversal/solution.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | from typing import List 3 | 4 | 5 | class TreeNode: 6 | def __init__(self, x): 7 | self.val = x 8 | self.left = None 9 | self.right = None 10 | 11 | 12 | class Solution: 13 | def __init__(self): 14 | self.levels = [] 15 | 16 | def levelOrder(self, root: TreeNode, level=0) -> List[List[int]]: 17 | if not root: 18 | return 19 | 20 | if len(self.levels) < level + 1: 21 | self.levels.append([]) 22 | 23 | self.levels[level].append(root.val) 24 | 25 | self.levelOrder(root.left, level + 1) 26 | self.levelOrder(root.right, level + 1) 27 | 28 | return self.levels 29 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/4_trees/convert_sorted_array_to_BST/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | tree := sortedArrayToBST([]int{1, 2, 3}) 7 | fmt.Println(tree.Val) // expected 2 8 | fmt.Println(tree.Left.Val) // expected 1 9 | fmt.Println(tree.Right.Val) // expected 3 10 | } 11 | 12 | type TreeNode struct { 13 | Val int 14 | Left *TreeNode 15 | Right *TreeNode 16 | } 17 | 18 | func sortedArrayToBST(nums []int) *TreeNode { 19 | if len(nums) == 0 { 20 | return nil 21 | } 22 | 23 | middle := len(nums) / 2 24 | left := sortedArrayToBST(nums[:middle]) 25 | right := sortedArrayToBST(nums[middle+1:]) 26 | 27 | root := &TreeNode{ 28 | nums[middle], 29 | left, 30 | right, 31 | } 32 | 33 | return root 34 | } 35 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/4_trees/convert_sorted_array_to_BST/solution.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | from typing import List 3 | 4 | 5 | class TreeNode: 6 | def __init__(self, x): 7 | self.val = x 8 | self.left = None 9 | self.right = None 10 | 11 | 12 | class Solution: 13 | def sortedArrayToBST(self, nums: List[int]) -> TreeNode: 14 | if not nums: 15 | return None 16 | 17 | mid = len(nums) // 2 18 | 19 | tree = TreeNode(nums[mid]) 20 | tree.left = self.sortedArrayToBST(nums[:mid]) 21 | tree.right = self.sortedArrayToBST(nums[mid + 1:]) 22 | 23 | return tree 24 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/4_trees/maximum_depth_of_binary_tree/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | 5 | } 6 | 7 | type TreeNode struct { 8 | Val int 9 | Left *TreeNode 10 | Right *TreeNode 11 | } 12 | 13 | func maxDepth(root *TreeNode) int { 14 | if root == nil { 15 | return 0 16 | } 17 | 18 | leftMaxDepth := maxDepth(root.Left) 19 | rightMaxDepth := maxDepth(root.Right) 20 | 21 | if leftMaxDepth > rightMaxDepth { 22 | return leftMaxDepth + 1 23 | } 24 | 25 | return rightMaxDepth + 1 26 | } 27 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/4_trees/maximum_depth_of_binary_tree/solution.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | class TreeNode: 3 | def __init__(self, x): 4 | self.val = x 5 | self.left = None 6 | self.right = None 7 | 8 | 9 | class Solution: 10 | def maxDepth(self, root: TreeNode) -> int: 11 | if not root: 12 | return 0 13 | 14 | return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1 15 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/4_trees/symmetric_tree/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | 5 | } 6 | 7 | type TreeNode struct { 8 | Val int 9 | Left *TreeNode 10 | Right *TreeNode 11 | } 12 | 13 | func isSymmetric(root *TreeNode) bool { 14 | return helper(root, root) 15 | } 16 | 17 | func helper(left, right *TreeNode) bool { 18 | if left == nil && right == nil { 19 | return true 20 | } 21 | 22 | if left == nil || right == nil { 23 | return false 24 | } 25 | 26 | return left.Val == right.Val && helper(left.Left, right.Right) && helper(left.Right, right.Left) 27 | } 28 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/4_trees/symmetric_tree/solution.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | class TreeNode: 3 | def __init__(self, x): 4 | self.val = x 5 | self.left = None 6 | self.right = None 7 | 8 | 9 | def is_symmetric(left, right): 10 | if not left and not right: 11 | return True 12 | 13 | if not left or not right: 14 | return False 15 | 16 | return left.val == right.val and is_symmetric(left.left, right.right) and is_symmetric(left.right, right.left) 17 | 18 | 19 | if __name__ == '__main__': 20 | t1 = TreeNode(1) 21 | t1.left = TreeNode(2) 22 | t1.right = TreeNode(2) 23 | t1.left.left = TreeNode(3) 24 | t1.left.right = TreeNode(4) 25 | t1.right.left = TreeNode(4) 26 | t1.right.right = TreeNode(3) 27 | 28 | t2 = TreeNode(1) 29 | t2.left = TreeNode(2) 30 | t2.right = TreeNode(2) 31 | t2.left.right = TreeNode(3) 32 | t2.right.right = TreeNode(3) 33 | 34 | assert is_symmetric(t1, t1) is True 35 | assert is_symmetric(t2, t2) is False 36 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/4_trees/validate_binary_search_tree/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | func main() { 9 | tree := &TreeNode{ 10 | Val: 2, 11 | Left: &TreeNode{ 12 | Val: 1, 13 | }, 14 | Right: &TreeNode{ 15 | Val: 3, 16 | }, 17 | } 18 | fmt.Print(isValidBST(tree)) // expected true 19 | } 20 | 21 | type TreeNode struct { 22 | Val int 23 | Left *TreeNode 24 | Right *TreeNode 25 | } 26 | 27 | func isValidBST(root *TreeNode) bool { 28 | return helper(root, math.MinInt16, math.MaxInt16) 29 | } 30 | 31 | func helper(root *TreeNode, min, max int) bool { 32 | if root == nil { 33 | return true 34 | } 35 | 36 | if root.Val < min || root.Val > max { 37 | return false 38 | } 39 | 40 | return helper(root.Left, min, root.Val) && helper(root.Right, root.Val, max) 41 | } 42 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/4_trees/validate_binary_search_tree/solution.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | class TreeNode: 3 | def __init__(self, x): 4 | self.val = x 5 | self.left = None 6 | self.right = None 7 | 8 | 9 | class Solution: 10 | def isValidBST(self, root: TreeNode) -> bool: 11 | return self.valid(root, float('-inf'), float('inf')) 12 | 13 | def valid(self, root, min_, max_): 14 | if not root: 15 | return True 16 | 17 | return min_ < root.val < max_ and self.valid(root.left, min_, root.val) and self.valid(root.right, root.val, max_) 18 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/5_sorting_and_searching/first_bad_version/solution.py: -------------------------------------------------------------------------------- 1 | # The isBadVersion API is already defined for you. 2 | def isBadVersion(version: int) -> bool: 3 | raise NotImplemented 4 | 5 | 6 | # TODO: simplify 7 | class Solution: 8 | def firstBadVersion(self, n): 9 | """ 10 | :type n: int 11 | :rtype: int 12 | """ 13 | min_ = 0 14 | max_ = n 15 | 16 | while min_ < max_: 17 | middle = (min_ + max_ + 1) // 2 18 | if isBadVersion(middle): 19 | max_ = middle 20 | else: 21 | min_ = middle 22 | 23 | if max_ - min_ == 1: 24 | if isBadVersion(min_): 25 | return min_ 26 | 27 | return max_ 28 | 29 | return middle 30 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/5_sorting_and_searching/merge_sorted_array/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None: 6 | """ 7 | Do not return anything, modify nums1 in-place instead. 8 | """ 9 | merged = [] 10 | i, j = 0, 0 11 | 12 | while i < m and j < n: 13 | if nums1[i] < nums2[j]: 14 | merged.append(nums1[i]) 15 | i += 1 16 | else: 17 | merged.append(nums2[j]) 18 | j += 1 19 | 20 | merged.extend(nums1[i:m]) 21 | merged.extend(nums2[j:n]) 22 | 23 | for i in range(len(merged)): 24 | nums1[i] = merged[i] 25 | 26 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/6_dynamic_programming/best_time_to_buy_and_sell_stock/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | 5 | } 6 | 7 | func maxProfit(prices []int) int { 8 | if len(prices) == 0 { 9 | return 0 10 | } 11 | 12 | maxVal, minVal := prices[0], prices[0] 13 | maxGain, currGain := 0, 0 14 | 15 | for _, price := range prices[1:] { 16 | if price > maxVal { 17 | maxVal = price 18 | currGain = maxVal - minVal 19 | if currGain > maxGain { 20 | maxGain = currGain 21 | } 22 | } 23 | 24 | if price < minVal { 25 | minVal = price 26 | maxVal = price 27 | currGain = 0 28 | } 29 | } 30 | 31 | return maxGain 32 | } 33 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/6_dynamic_programming/best_time_to_buy_and_sell_stock/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def maxProfit(self, prices: List[int]) -> int: 6 | if not prices: 7 | return 0 8 | 9 | max_val = min_val = prices[0] 10 | max_gain = current_gain = 0 11 | 12 | for index in range(1, len(prices)): 13 | 14 | if prices[index] > max_val: 15 | max_val = prices[index] 16 | current_gain = max_val - min_val 17 | max_gain = current_gain if max_gain < current_gain else max_gain 18 | 19 | if prices[index] < min_val: 20 | min_val = max_val = prices[index] 21 | current_gain = 0 22 | 23 | return max_gain 24 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/6_dynamic_programming/climbing_stairs/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println(climbStairs(2)) 7 | fmt.Println(climbStairs(3)) 8 | fmt.Println(climbStairs(4)) 9 | fmt.Println(climbStairs(5)) 10 | } 11 | 12 | func climbStairs(n int) int { 13 | return fib(n) 14 | } 15 | 16 | func fib(n int) int { 17 | a, b := 0, 1 18 | 19 | for a < n { 20 | a, b = b, a+b 21 | } 22 | 23 | return b 24 | } 25 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/6_dynamic_programming/climbing_stairs/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def climbStairs(self, n: int) -> int: 3 | "Fibonacci" 4 | a, b = 1, 1 5 | 6 | i = 1 7 | while i < n: 8 | i += 1 9 | a = a + b 10 | b = a - b 11 | 12 | return a 13 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/6_dynamic_programming/house_robber/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println(rob([]int{1, 2, 3, 1})) // expected 4 7 | fmt.Println(rob([]int{2, 7, 9, 3, 1})) // expected 12 8 | } 9 | 10 | func rob(nums []int) int { 11 | if len(nums) == 0 { 12 | return 0 13 | } 14 | 15 | if len(nums) == 1 { 16 | return nums[0] 17 | } 18 | 19 | dp := make([]int, len(nums)) 20 | dp[0] = nums[0] 21 | dp[1] = max(nums[0], nums[1]) 22 | 23 | for i := 2; i < len(dp); i++ { 24 | dp[i] = max(dp[i-1], dp[i-2]+nums[i]) 25 | } 26 | 27 | return dp[len(dp)-1] 28 | } 29 | 30 | func max(a, b int) int { 31 | if a > b { 32 | return a 33 | } 34 | 35 | return b 36 | } 37 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/6_dynamic_programming/house_robber/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def rob(self, nums): 3 | if not nums: 4 | return 0 5 | 6 | if len(nums) == 1: 7 | return nums[0] 8 | 9 | dp = [0 for _ in nums] 10 | dp[0] = nums[0] 11 | dp[1] = max(nums[0], nums[1]) 12 | 13 | for index in range(2, len(nums)): 14 | dp[index] = max(dp[index - 1], dp[index - 2] + nums[index]) 15 | 16 | return dp[-1] 17 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/6_dynamic_programming/maximum_subarray/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | 5 | } 6 | 7 | func maxSubArray(nums []int) int { 8 | if len(nums) == 1 { 9 | return nums[0] 10 | } 11 | 12 | maxSum, currSum := nums[0], nums[0] 13 | 14 | for _, num := range nums[1:] { 15 | currSum = max(currSum+num, num) 16 | 17 | if currSum > maxSum { 18 | maxSum = currSum 19 | } 20 | } 21 | 22 | return maxSum 23 | } 24 | 25 | func max(a, b int) int { 26 | if a > b { 27 | return a 28 | } 29 | 30 | return b 31 | } 32 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/6_dynamic_programming/maximum_subarray/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def maxSubArray(self, nums: List[int]) -> int: 6 | n = len(nums) 7 | if n == 1: 8 | return nums[0] 9 | 10 | max_sum = curr_sum = nums[0] 11 | 12 | for num in nums[1:]: 13 | curr_sum = max(curr_sum + num, num) 14 | 15 | if curr_sum > max_sum: 16 | max_sum = curr_sum 17 | 18 | return max_sum 19 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/7_design/min_stack/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | type Node struct { 4 | val int 5 | minSoFar int 6 | } 7 | 8 | type MinStack struct { 9 | stack []Node 10 | } 11 | 12 | /** initialize your data structure here. */ 13 | func Constructor() MinStack { 14 | return MinStack{stack: []Node{}} 15 | } 16 | 17 | func (s *MinStack) Push(x int) { 18 | length := len(s.stack) 19 | min := x 20 | if length > 0 { 21 | minSoFar := s.stack[length-1].minSoFar 22 | if min > minSoFar { 23 | min = minSoFar 24 | } 25 | } 26 | 27 | s.stack = append(s.stack, Node{ 28 | val: x, 29 | minSoFar: min, 30 | }) 31 | } 32 | 33 | func (s *MinStack) Pop() { 34 | length := len(s.stack) 35 | s.stack = s.stack[:length-1] 36 | } 37 | 38 | func (s *MinStack) Top() int { 39 | length := len(s.stack) 40 | return s.stack[length-1].val 41 | } 42 | 43 | func (s *MinStack) GetMin() int { 44 | length := len(s.stack) 45 | return s.stack[length-1].minSoFar 46 | } 47 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/7_design/min_stack/solution.py: -------------------------------------------------------------------------------- 1 | class Node: 2 | def __init__(self, value, min_value): 3 | self.value = value 4 | self.min_value = min_value 5 | 6 | 7 | class MinStack: 8 | 9 | def __init__(self): 10 | """ 11 | initialize your data structure here. 12 | """ 13 | self.stack = [] 14 | 15 | def push(self, value: int) -> None: 16 | min_value = value 17 | if len(self.stack) > 0: 18 | prev_min_value = self.stack[-1].min_value 19 | min_value = min(prev_min_value, min_value) 20 | 21 | node = Node(value, min_value) 22 | self.stack.append(node) 23 | 24 | def pop(self) -> None: 25 | self.stack.pop() 26 | 27 | def top(self) -> int: 28 | return self.stack[-1].value 29 | 30 | def getMin(self) -> int: 31 | return self.stack[-1].min_value 32 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/7_design/shuffle_an_array/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "math/rand" 4 | 5 | type Solution struct { 6 | nums []int 7 | original []int 8 | } 9 | 10 | func Constructor(nums []int) Solution { 11 | original := make([]int, len(nums)) 12 | copy(original, nums) 13 | 14 | return Solution{ 15 | nums: nums, 16 | original: original, 17 | } 18 | } 19 | 20 | /** Resets the array to its original configuration and return it. */ 21 | func (this *Solution) Reset() []int { 22 | this.nums = this.original 23 | 24 | return this.original 25 | } 26 | 27 | /** Returns a random shuffling of the array. */ 28 | func (this *Solution) Shuffle() []int { 29 | var randIndex int 30 | length := len(this.nums) 31 | 32 | for i := 0; i < length; i++ { 33 | randIndex = rand.Intn(length) 34 | this.nums[i], this.nums[randIndex] = this.nums[randIndex], this.nums[i] 35 | } 36 | 37 | return this.nums 38 | } 39 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/7_design/shuffle_an_array/solution.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | class Solution: 5 | def __init__(self, nums): 6 | self.array = nums 7 | self.original = list(nums) 8 | 9 | def reset(self): 10 | self.array = self.original 11 | self.original = list(self.original) 12 | return self.array 13 | 14 | def shuffle(self): 15 | for i in range(len(self.array)): 16 | swap_idx = random.randrange(i, len(self.array)) 17 | self.array[i], self.array[swap_idx] = self.array[swap_idx], self.array[i] 18 | 19 | return self.array 20 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/8_math/count_primes/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | func main() { 9 | fmt.Println(countPrimes(10)) // expected 4 10 | } 11 | 12 | func countPrimes(n int) int { 13 | var primes []int 14 | numbers := make(map[int]bool) 15 | 16 | for i := 2; i < n; i++ { 17 | numbers[i] = true 18 | } 19 | 20 | for i := 2; i < int(math.Sqrt(float64(n)))+1; i++ { 21 | if isPrime(i) { 22 | primes = append(primes, i) 23 | } 24 | } 25 | 26 | for _, prime := range primes { 27 | for i := prime * prime; i < n; i += prime { 28 | if i%prime == 0 { 29 | numbers[i] = false 30 | } 31 | } 32 | } 33 | 34 | total := 0 35 | for _, prime := range numbers { 36 | if prime { 37 | total++ 38 | } 39 | } 40 | 41 | return total 42 | } 43 | 44 | func isPrime(n int) bool { 45 | if n == 2 { 46 | return true 47 | } 48 | 49 | for i := 2; i <= int(math.Sqrt(float64(n))); i++ { 50 | if n%i == 0 { 51 | return false 52 | } 53 | } 54 | 55 | return true 56 | } 57 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/8_math/count_primes/solution.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | 4 | class Solution: 5 | def countPrimes(self, n: int) -> int: 6 | primes = [] 7 | numbers = {i: True for i in range(2, n)} 8 | 9 | for i in range(2, int(math.sqrt(n)) + 1): 10 | if self.isPrime(i): 11 | primes.append(i) 12 | 13 | for prime in primes: 14 | for i in range(prime * prime, n, prime): 15 | if i % prime == 0: 16 | numbers[i] = False 17 | 18 | return sum(numbers.values()) 19 | 20 | def isPrime(self, n): 21 | if n == 2: 22 | return True 23 | 24 | for i in range(2, int(math.sqrt(n)) + 1): 25 | if n % i == 0: 26 | return False 27 | 28 | return True 29 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/8_math/fizz_buzz/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | func main() { 9 | fmt.Println(fizzBuzz(20)) 10 | } 11 | 12 | func fizzBuzz(n int) []string { 13 | result := []string{} 14 | 15 | for i := 1; i <= n; i++ { 16 | if i%15 == 0 { 17 | result = append(result, "FizBuzz") 18 | } else if i%5 == 0 { 19 | result = append(result, "Buzz") 20 | } else if i%3 == 0 { 21 | result = append(result, "Fiz") 22 | } else { 23 | result = append(result, strconv.Itoa(i)) 24 | } 25 | } 26 | 27 | return result 28 | } 29 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/8_math/fizz_buzz/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def fizzBuzz(self, n: int) -> List[str]: 3 | result = [] 4 | 5 | for i in range(1, n + 1): 6 | if i % 15 == 0: 7 | string = "FizzBuzz" 8 | elif i % 5 == 0: 9 | string = "Buzz" 10 | elif i % 3 == 0: 11 | string = "Fizz" 12 | else: 13 | string = str(i) 14 | 15 | result.append(string) 16 | 17 | return result 18 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/8_math/power_of_tree/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println(isPowerOfThree(27)) // expected true 7 | fmt.Println(isPowerOfThree(818)) // expected false 8 | } 9 | 10 | func isPowerOfThree(n int) bool { 11 | if n == 1 { 12 | return true 13 | } 14 | 15 | if n < 1 || n%3 != 0 { 16 | return false 17 | } 18 | 19 | return isPowerOfThree(n / 3) 20 | } 21 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/8_math/power_of_tree/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isPowerOfThree(self, n: int) -> bool: 3 | if n == 1: 4 | return True 5 | 6 | if n < 1 or n % 3 != 0: 7 | return False 8 | 9 | return self.isPowerOfThree(int(n / 3)) 10 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/8_math/roman_to_integer/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println(romanToInt("III")) // expected 3 7 | } 8 | 9 | func romanToInt(s string) int { 10 | romanMap := map[rune]int{ 11 | 'I': 1, 12 | 'V': 5, 13 | 'X': 10, 14 | 'L': 50, 15 | 'C': 100, 16 | 'D': 500, 17 | 'M': 1000, 18 | } 19 | total, prev := 0, 0 20 | 21 | for _, c := range s { 22 | current := romanMap[c] 23 | 24 | if current < prev { 25 | total -= prev 26 | } else { 27 | total += prev 28 | } 29 | prev = current 30 | } 31 | 32 | total += prev 33 | 34 | return total 35 | } 36 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/8_math/roman_to_integer/solution.py: -------------------------------------------------------------------------------- 1 | roman_dict = { 2 | 'I': 1, 3 | 'V': 5, 4 | 'X': 10, 5 | 'L': 50, 6 | 'C': 100, 7 | 'D': 500, 8 | 'M': 1000, 9 | } 10 | 11 | 12 | class Solution: 13 | def romanToInt(self, s: str) -> int: 14 | prev = 0 15 | total = 0 16 | for char in s: 17 | current = roman_dict[char] 18 | 19 | if prev < current: 20 | total -= prev 21 | else: 22 | total += prev 23 | 24 | prev = current 25 | 26 | total += prev 27 | 28 | return total 29 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/9_others/hamming_distance/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println(hammingDistance(3, 8)) // expected 3 7 | } 8 | 9 | func hammingDistance(x, y int) int { 10 | xor := x ^ y 11 | difference := 0 12 | 13 | for xor != 0 { 14 | difference += xor & 1 15 | xor = xor >> 1 16 | } 17 | 18 | return difference 19 | } 20 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/9_others/hamming_distance/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def hammingDistance(self, x: int, y: int) -> int: 3 | xor = x ^ y 4 | differences = 0 5 | 6 | while xor: 7 | differences += xor & 1 8 | xor = xor >> 1 9 | 10 | return differences 11 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/9_others/missing_number/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func main() { 8 | fmt.Println(missingNumber([]int{0, 1, 2, 3, 5})) // expected 4 9 | fmt.Println(missingNumber([]int{0, 1, 2, 3})) // expected 4 10 | } 11 | 12 | func missingNumber(nums []int) int { 13 | length := len(nums) 14 | result := (length + 1) * length / 2 15 | 16 | for i := 0; i < length; i++ { 17 | result -= nums[i] 18 | } 19 | 20 | return result 21 | } 22 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/9_others/missing_number/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def missingNumber(self, nums: List[int]) -> int: 6 | max_num = max(nums) 7 | nums = set(nums) 8 | 9 | for i in range(max_num): 10 | if i not in nums: 11 | return i 12 | 13 | return max_num + 1 14 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/9_others/number_of_1_bits/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println(hammingWeight(1)) // expected 1 7 | fmt.Println(hammingWeight(4)) // expected 1 8 | fmt.Println(hammingWeight(5)) // expected 2 9 | } 10 | 11 | func hammingWeight(n uint32) int { 12 | x := int(n) 13 | numOnes := 0 14 | 15 | for x != 0 { 16 | numOnes += x & 1 17 | x = x >> 1 18 | } 19 | 20 | return numOnes 21 | } 22 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/9_others/number_of_1_bits/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def hammingWeight(self, n: int) -> int: 3 | count = 0 4 | 5 | while n != 0: 6 | n = n & (n - 1) 7 | count += 1 8 | 9 | return count 10 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/9_others/pascals_triangle/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | triangle := generate(10) 7 | for _, row := range triangle { 8 | fmt.Println(row) 9 | } 10 | } 11 | 12 | func generate(numRows int) [][]int { 13 | rows := make([][]int, numRows) 14 | 15 | for i := 0; i < numRows; i++ { 16 | for j := 0; j < i+1; j++ { 17 | rows[i] = append(rows[i], 1) 18 | } 19 | } 20 | 21 | for i := 1; i < numRows; i++ { 22 | for j := 1; j < i; j++ { 23 | rows[i][j] = rows[i-1][j-1] + rows[i-1][j] 24 | } 25 | } 26 | 27 | return rows 28 | } 29 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/9_others/pascals_triangle/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def generate(self, numRows: int) -> List[List[int]]: 6 | rows = [[1 for j in range(i)] for i in range(1, numRows + 1)] 7 | 8 | for i in range(2, numRows): 9 | for j in range(1, i): 10 | rows[i][j] = rows[i - 1][j - 1] + rows[i - 1][j] 11 | 12 | return rows 13 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/9_others/reverse_bits/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | } 5 | 6 | func reverseBits(num uint32) uint32 { 7 | var reversed uint32 = 0 8 | 9 | for i := 0; i < 32; i++ { 10 | lastDigit := num & 1 11 | reversed = reversed << 1 12 | reversed += lastDigit 13 | num = num >> 1 14 | } 15 | 16 | return reversed 17 | } 18 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/9_others/reverse_bits/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def reverseBits(self, n: int) -> int: 3 | reversed_ = 0 4 | 5 | for _ in range(32): 6 | reversed_ = reversed_ << 1 7 | reversed_ += (n & 1) 8 | n = n >> 1 9 | 10 | return reversed_ 11 | 12 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/9_others/valid_parentheses/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println(isValid("[(){}]")) // expected true 7 | fmt.Println(isValid("[(){])")) // expected false 8 | } 9 | 10 | type stack []rune 11 | 12 | func (s stack) Push(v rune) stack { 13 | return append(s, v) 14 | } 15 | 16 | func (s stack) Pop() (stack, rune) { 17 | l := len(s) 18 | return s[:l-1], s[l-1] 19 | } 20 | 21 | func isValid(s string) bool { 22 | var stack stack 23 | var close_ rune 24 | 25 | braces := map[rune]rune{ 26 | '}': '{', 27 | ']': '[', 28 | ')': '(', 29 | } 30 | 31 | for _, c := range s { 32 | open, exists := braces[c] 33 | if exists { 34 | if len(stack) > 0 { 35 | stack, close_ = stack.Pop() 36 | if open != close_ { 37 | return false 38 | } 39 | } else { 40 | return false 41 | } 42 | } else { 43 | stack = stack.Push(c) 44 | } 45 | } 46 | 47 | return len(stack) == 0 48 | } 49 | -------------------------------------------------------------------------------- /top_interview_questions/1_easy/9_others/valid_parentheses/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def isValid(self, string: str) -> bool: 3 | stack = [] 4 | braces = {"}": "{", ")": "(", "]": "["} 5 | 6 | for character in string: 7 | if character in braces.values(): 8 | stack.append(character) 9 | elif character in braces.keys(): 10 | try: 11 | if braces[character] != stack.pop(): 12 | return False 13 | except IndexError: 14 | return False 15 | 16 | return not stack 17 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/1_array_and_strings/3sum/solution.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azimjohn/leetcode/463d9bdf53bfb6f10f1e5c8b233a28107351b82e/top_interview_questions/2_medium/1_array_and_strings/3sum/solution.py -------------------------------------------------------------------------------- /top_interview_questions/2_medium/1_array_and_strings/group_anagrams/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | ) 7 | 8 | func main() { 9 | fmt.Println(groupAnagrams([]string{"eat", "tea", "tan", "ate", "nat", "bat"})) 10 | /* Expected 11 | [ 12 | ["ate","eat","tea"], 13 | ["nat","tan"], 14 | ["bat"] 15 | ] 16 | */ 17 | } 18 | 19 | func groupAnagrams(strs []string) [][]string { 20 | var key string 21 | var groups [][]string 22 | hashMap := make(map[string][]string) 23 | 24 | for _, str := range strs { 25 | key = anagramKey(str) 26 | hashMap[key] = append(hashMap[key], str) 27 | } 28 | 29 | for _, v := range hashMap { 30 | groups = append(groups, v) 31 | } 32 | 33 | return groups 34 | } 35 | 36 | func anagramKey(s string) string { 37 | r := []byte(s) 38 | 39 | sort.Slice(r, func(i, j int) bool { 40 | return r[i] < r[j] 41 | }) 42 | 43 | return string(r) 44 | } 45 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/1_array_and_strings/group_anagrams/solution.py: -------------------------------------------------------------------------------- 1 | import collections 2 | from typing import List 3 | 4 | 5 | class Solution: 6 | def groupAnagrams(self, strs: List[str]) -> List[List[str]]: 7 | groups = collections.defaultdict(list) 8 | 9 | for s in strs: 10 | key = tuple(sorted(s)) 11 | groups[key].append(s) 12 | 13 | return list(groups.values()) 14 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/1_array_and_strings/increasing_triplet_subsequence/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | func main() { 9 | fmt.Println(increasingTriplet([]int{1, 2, 3, 4, 5})) // true 10 | fmt.Println(increasingTriplet([]int{5, 4, 3, 2, 1})) // false 11 | } 12 | 13 | func increasingTriplet(nums []int) bool { 14 | if len(nums) == 0 { 15 | return false 16 | } 17 | 18 | min := nums[0] 19 | middle := math.MinInt32 20 | 21 | for _, num := range nums[1:] { 22 | if min > num { 23 | min = num 24 | } 25 | 26 | if middle == math.MinInt32 { 27 | if num > min { 28 | middle = num 29 | } 30 | continue 31 | } 32 | 33 | if middle > num && num > min { 34 | middle = num 35 | } 36 | 37 | if num > middle && middle > min { 38 | return true 39 | } 40 | } 41 | 42 | return false 43 | } 44 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/1_array_and_strings/increasing_triplet_subsequence/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def increasingTriplet(self, nums: List[int]) -> bool: 6 | if not nums: 7 | return False 8 | 9 | min_ = nums[0] 10 | middle = None 11 | 12 | for num in nums[1:]: 13 | if min_ > num: 14 | min_ = num 15 | 16 | if middle is None: 17 | if num > min_: 18 | middle = num 19 | continue 20 | 21 | if middle > num > min_: 22 | middle = num 23 | 24 | if num > middle > min_: 25 | return True 26 | 27 | return False 28 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/1_array_and_strings/longest_palindromic_substring/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println(longestPalindrome("babad")) // bab 7 | fmt.Println(longestPalindrome("cbbd")) // bb 8 | } 9 | 10 | func longestPalindrome(s string) string { 11 | s = duplicateChars(s) 12 | longest := "" 13 | current := "" 14 | length := len(s) 15 | 16 | for n := 0; n < length; n++ { 17 | i := 0 18 | for n-i >= 0 && n+i < length-1 { 19 | fmt.Println(n, i) 20 | if s[n-i] != s[n+i+1] { 21 | break 22 | } 23 | i++ 24 | } 25 | 26 | current = s[n-i+1 : n+i+1] 27 | if len(current) > len(longest) { 28 | longest = current 29 | } 30 | } 31 | 32 | return removeDuplicates(longest) 33 | } 34 | 35 | func duplicateChars(s string) string { 36 | r := "" 37 | 38 | for _, char := range s { 39 | r += string(char) 40 | r += string(char) 41 | } 42 | 43 | return r 44 | } 45 | 46 | func removeDuplicates(s string) string { 47 | r := "" 48 | for i, char := range s { 49 | if i%2 == 0 { 50 | r += string(char) 51 | } 52 | } 53 | 54 | return r 55 | } 56 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/1_array_and_strings/longest_palindromic_substring/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def longestPalindrome(self, s: str) -> str: 3 | s = self.duplicateChars(s) 4 | longest = "" 5 | current = "" 6 | length = len(s) 7 | 8 | for n in range(0, length): 9 | i = 0 10 | while n - i >= 0 and n + i < length - 1: 11 | if not s[n - i] == s[n + i + 1]: 12 | break 13 | i += 1 14 | 15 | current = s[n - i + 1:n + i + 1] 16 | longest = max(longest, current, key=len) 17 | 18 | return longest[::2] # undo the duplicationg 19 | 20 | def duplicateChars(self, s: str) -> str: 21 | chars = [] 22 | for char in s: 23 | chars.append(char) 24 | chars.append(char) 25 | 26 | return ''.join(chars) 27 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/1_array_and_strings/longest_substr_without_repeating_chars/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | fmt.Println(lengthOfLongestSubstring("abcabcbb")) // expected 3 7 | fmt.Println(lengthOfLongestSubstring("bbbbb")) // expected 1 8 | fmt.Println(lengthOfLongestSubstring("pwwkew")) // expected 3 9 | } 10 | 11 | func lengthOfLongestSubstring(s string) int { 12 | if len(s) == 0 { 13 | return 0 14 | } 15 | 16 | length := len(s) 17 | longest := 1 18 | hashMap := make(map[uint8]int) 19 | i, j := 0, 0 20 | 21 | for j < length { 22 | char := s[j] 23 | if _, ok := hashMap[char]; ok { 24 | i = max(i, hashMap[char]) 25 | } 26 | 27 | longest = max(longest, j-i+1) 28 | hashMap[char] = j + 1 29 | j += 1 30 | } 31 | 32 | return longest 33 | } 34 | 35 | func max(a, b int) int { 36 | if a > b { 37 | return a 38 | } 39 | 40 | return b 41 | } 42 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/1_array_and_strings/longest_substr_without_repeating_chars/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def lengthOfLongestSubstring(self, s: str) -> int: 3 | if not s: 4 | return 0 5 | 6 | longest = 1 7 | length = len(s) 8 | dict_ = dict() 9 | i, j = 0, 0 10 | 11 | while j < length: 12 | char = s[j] 13 | if char in dict_: 14 | i = max(i, dict_[char]) 15 | 16 | longest = max(longest, j - i + 1) 17 | dict_[char] = j + 1 18 | 19 | j += 1 20 | 21 | return longest 22 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/1_array_and_strings/set_matrix_zeroes/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func setZeroes(matrix [][]int) { 4 | zeroCols := make(map[int]bool) 5 | zeroRows := make(map[int]bool) 6 | numCols, numRows := len(matrix), len(matrix[0]) 7 | 8 | for i, col := range matrix { 9 | for j, elem := range col { 10 | if elem == 0 { 11 | zeroCols[i] = true 12 | zeroRows[j] = true 13 | } 14 | } 15 | } 16 | 17 | for col, _ := range zeroCols { 18 | for row := 0; row < numRows; row++ { 19 | matrix[col][row] = 0 20 | } 21 | } 22 | 23 | for col := 0; col < numCols; col++ { 24 | for row, _ := range zeroRows { 25 | matrix[col][row] = 0 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/1_array_and_strings/set_matrix_zeroes/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def setZeroes(self, matrix: List[List[int]]) -> None: 6 | """ 7 | Do not return anything, modify matrix in-place instead. 8 | """ 9 | rows = len(matrix) 10 | cols = len(matrix[0]) 11 | zero_rows, zero_cols = set(), set() 12 | 13 | for i in range(rows): 14 | for j in range(cols): 15 | if matrix[i][j] == 0: 16 | zero_rows.add(i) 17 | zero_cols.add(j) 18 | 19 | for row in zero_rows: 20 | for col in range(cols): 21 | matrix[row][col] = 0 22 | 23 | for col in zero_cols: 24 | for row in range(rows): 25 | matrix[row][col] = 0 26 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/2_linked_list/add_two_numbers/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func main() { 6 | a := &ListNode{ 7 | Val: 2, 8 | Next: &ListNode{ 9 | Val: 4, 10 | Next: &ListNode{Val: 3}, 11 | }, 12 | } 13 | b := &ListNode{ 14 | Val: 5, 15 | Next: &ListNode{ 16 | Val: 6, 17 | Next: &ListNode{Val: 4}, 18 | }, 19 | } 20 | 21 | sum := addTwoNumbers(a, b) 22 | for sum != nil { 23 | fmt.Print(sum.Val, " ") 24 | sum = sum.Next 25 | } 26 | } 27 | 28 | type ListNode struct { 29 | Val int 30 | Next *ListNode 31 | } 32 | 33 | func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode { 34 | sum := l1.Val + l2.Val 35 | carry := int(sum / 10) 36 | result := &ListNode{Val: sum % 10} 37 | resultHead := result 38 | 39 | l1 = l1.Next 40 | l2 = l2.Next 41 | 42 | for l1 != nil || l2 != nil { 43 | sum = carry 44 | 45 | if l1 != nil { 46 | sum += l1.Val 47 | l1 = l1.Next 48 | } 49 | 50 | if l2 != nil { 51 | sum += l2.Val 52 | l2 = l2.Next 53 | } 54 | 55 | carry = int(sum / 10) 56 | result.Next = &ListNode{Val: sum % 10} 57 | result = result.Next 58 | } 59 | 60 | if carry != 0 { 61 | result.Next = &ListNode{Val: carry} 62 | } 63 | 64 | return resultHead 65 | } 66 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/2_linked_list/add_two_numbers/solution.py: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/problems/add-two-numbers/ 2 | 3 | # Definition for singly-linked list. 4 | class ListNode: 5 | def __init__(self, x): 6 | self.val = x 7 | self.next = None 8 | 9 | 10 | class Solution: 11 | def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode: 12 | sum_ = l1.val + l2.val 13 | carry = sum_ // 10 14 | result = ListNode(sum_ % 10) 15 | result_head = result 16 | 17 | l1 = l1.next 18 | l2 = l2.next 19 | 20 | while l1 or l2: 21 | sum_ = (l1.val if l1 else 0) + (l2.val if l2 else 0) + carry 22 | carry = sum_ // 10 23 | result.next = ListNode(sum_ % 10) 24 | 25 | if l1: 26 | l1 = l1.next 27 | 28 | if l2: 29 | l2 = l2.next 30 | 31 | result = result.next 32 | 33 | if carry: 34 | result.next = ListNode(carry) 35 | 36 | return result_head 37 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/2_linked_list/intersection_of_two_linked_lists/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | 5 | } 6 | 7 | type ListNode struct { 8 | Val int 9 | Next *ListNode 10 | } 11 | 12 | func getIntersectionNode(headA, headB *ListNode) *ListNode { 13 | visited := make(map[*ListNode]bool) 14 | 15 | for headA != nil { 16 | visited[headA] = true 17 | headA = headA.Next 18 | } 19 | 20 | for headB != nil { 21 | if _, ok := visited[headB]; ok { 22 | return headB 23 | } 24 | headB = headB.Next 25 | } 26 | 27 | return nil 28 | } 29 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/2_linked_list/intersection_of_two_linked_lists/solution.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 | class Solution: 8 | def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode: 9 | while headB: 10 | headB.is_b = True 11 | headB = headB.next 12 | 13 | while headA: 14 | if hasattr(headA, "is_b"): 15 | return headA 16 | 17 | headA = headA.next 18 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/2_linked_list/odd_even_linked_list/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | 5 | } 6 | 7 | type ListNode struct { 8 | Val int 9 | Next *ListNode 10 | } 11 | 12 | func oddEvenList(head *ListNode) *ListNode { 13 | if head == nil || head.Next == nil { 14 | return head 15 | } 16 | 17 | odd := &ListNode{Val: head.Val} 18 | even := &ListNode{Val: head.Next.Val} 19 | oddHead := odd 20 | evenHead := even 21 | 22 | head = head.Next.Next 23 | 24 | i := 0 25 | for head != nil { 26 | if i%2 == 0 { 27 | odd.Next = &ListNode{Val: head.Val} 28 | odd = odd.Next 29 | } else { 30 | even.Next = &ListNode{Val: head.Val} 31 | even = even.Next 32 | } 33 | 34 | head = head.Next 35 | i++ 36 | } 37 | 38 | odd.Next = evenHead 39 | return oddHead 40 | } 41 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/2_linked_list/odd_even_linked_list/solution.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 | class Solution: 9 | def oddEvenList(self, head: ListNode) -> ListNode: 10 | if not head or not head.next: 11 | return head 12 | 13 | even = ListNode(head.val) 14 | odd = ListNode(head.next.val) 15 | even_head = even 16 | odd_head = odd 17 | head = head.next.next 18 | 19 | i = 0 20 | while head: 21 | if i % 2 == 0: 22 | even.next = ListNode(head.val) 23 | even = even.next 24 | else: 25 | odd.next = ListNode(head.val) 26 | odd = odd.next 27 | 28 | head = head.next 29 | i += 1 30 | 31 | even.next = odd_head 32 | return even_head 33 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/3_trees_and_graphs/binary_tree_inorder_traversal/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | 5 | } 6 | 7 | type TreeNode struct { 8 | Val int 9 | Left *TreeNode 10 | Right *TreeNode 11 | } 12 | 13 | func inorderTraversal(root *TreeNode) []int { 14 | var result []int 15 | var s stack 16 | current := root 17 | 18 | for len(s) != 0 || current != nil { 19 | for current != nil { 20 | s = s.Push(current) 21 | current = current.Left 22 | } 23 | 24 | s, current = s.Pop() 25 | result = append(result, current.Val) 26 | current = current.Right 27 | } 28 | 29 | return result 30 | } 31 | 32 | type stack []*TreeNode 33 | 34 | func (s stack) Push(v *TreeNode) stack { 35 | return append(s, v) 36 | } 37 | 38 | func (s stack) Pop() (stack, *TreeNode) { 39 | l := len(s) 40 | return s[:l-1], s[l-1] 41 | } 42 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/3_trees_and_graphs/binary_tree_inorder_traversal/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class TreeNode: 5 | def __init__(self, x): 6 | self.val = x 7 | self.left = None 8 | self.right = None 9 | 10 | 11 | class Solution: 12 | def inorderTraversal(self, root: TreeNode) -> List[int]: 13 | result = [] 14 | stack = [] 15 | current = root 16 | 17 | while stack or current: 18 | while current: 19 | stack.append(current) 20 | current = current.left 21 | 22 | current = stack.pop() 23 | result.append(current.val) 24 | current = current.right 25 | 26 | return result 27 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/3_trees_and_graphs/binary_tree_zigzag_level_order_traversal/solution.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | from typing import List 3 | 4 | 5 | class TreeNode: 6 | def __init__(self, x): 7 | self.val = x 8 | self.left = None 9 | self.right = None 10 | 11 | 12 | class Solution: 13 | def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]: 14 | self.levels = [] 15 | self.levelOrder(root) 16 | 17 | for i in range(len(self.levels)): 18 | if i % 2: 19 | self.levels[i] = list(reversed(self.levels[i])) 20 | 21 | return self.levels 22 | 23 | def levelOrder(self, root: TreeNode, level=0): 24 | if not root: 25 | return 26 | 27 | if len(self.levels) < level + 1: 28 | self.levels.append([]) 29 | 30 | self.levels[level].append(root.val) 31 | 32 | self.levelOrder(root.left, level + 1) 33 | self.levelOrder(root.right, level + 1) 34 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/3_trees_and_graphs/construct_binary_tree_from_preorder_and_inorder_traversal/solution.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | class TreeNode: 3 | def __init__(self, x): 4 | self.val = x 5 | self.left = None 6 | self.right = None 7 | 8 | 9 | class Solution: 10 | def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode: 11 | if not preorder: 12 | return None 13 | 14 | root = TreeNode(preorder[0]) 15 | try: 16 | index = inorder.index(root.val) 17 | except ValueError: 18 | return None 19 | 20 | left, right = inorder[:index], inorder[index+1:] 21 | 22 | root.left = self.buildTree(preorder[1:index+1], left) 23 | root.right = self.buildTree(preorder[index+1:], right) 24 | 25 | return root 26 | 27 | 28 | if __name__ == '__main__': 29 | s = Solution() 30 | s.buildTree([3, 20, 15, 7], [3, 15, 20, 7]) 31 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/3_trees_and_graphs/kth_smallest_element_in_a_bst/solution.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node. 2 | class TreeNode: 3 | def __init__(self, x): 4 | self.val = x 5 | self.left = None 6 | self.right = None 7 | 8 | 9 | class Solution: 10 | def kthSmallest(self, root: TreeNode, k: int) -> int: 11 | current = root 12 | stack = [] 13 | 14 | i = 0 15 | while True: 16 | if current: 17 | stack.append(current) 18 | current = current.left 19 | continue 20 | 21 | if stack: 22 | current = stack.pop() 23 | i += 1 24 | if i == k: 25 | return current.val 26 | 27 | current = current.right 28 | continue 29 | 30 | break 31 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/3_trees_and_graphs/number_of_islands/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | neighbours = [[-1, 0], [0, -1], [1, 0], [0, 1]] 3 | 4 | def numIslands(self, grid): 5 | if not grid or not grid[0]: 6 | return 0 7 | 8 | count = 0 9 | visited = [[False for row in column] for column in grid] 10 | rows = len(grid) 11 | cols = len(grid[0]) 12 | 13 | for i in range(rows): 14 | for j in range(cols): 15 | if not visited[i][j] and grid[i][j] == '1': 16 | self.dfs(grid, i, j, visited) 17 | count += 1 18 | 19 | return count 20 | 21 | def dfs(self, grid, i, j, visited): 22 | if not self.in_border(grid, i, j) or visited[i][j] or grid[i][j] == '0': 23 | return 24 | 25 | visited[i][j] = True 26 | for neighbour in self.neighbours: 27 | self.dfs(grid, i + neighbour[0], j + neighbour[1], visited) 28 | 29 | def in_border(self, grid, i, j): 30 | if i < 0 or j < 0: 31 | return False 32 | 33 | if i >= len(grid) or j >= len(grid[0]): 34 | return False 35 | 36 | return True 37 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/3_trees_and_graphs/populating_next_right_pointers_in_each_node/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | # Definition for a Node. 3 | class Node: 4 | def __init__(self, val: int = 0, left: 'Node' = None, right: 'Node' = None, next: 'Node' = None): 5 | self.val = val 6 | self.left = left 7 | self.right = right 8 | self.next = next 9 | """ 10 | 11 | 12 | class Solution: 13 | def __init__(self): 14 | self.levels = [] 15 | 16 | def connect(self, root: 'Node') -> 'Node': 17 | self.levelOrder(root) 18 | 19 | for level in self.levels: 20 | for i in range(len(level)-1): 21 | level[i].next = level[i+1] 22 | 23 | return root 24 | 25 | def levelOrder(self, root: TreeNode, level=0) -> List[List[int]]: 26 | if not root: 27 | return 28 | 29 | if len(self.levels) < level + 1: 30 | self.levels.append([]) 31 | 32 | self.levels[level].append(root) 33 | 34 | self.levelOrder(root.left, level+1) 35 | self.levelOrder(root.right, level+1) 36 | 37 | return self.levels 38 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/4_backtracking/generate_parentheses/solution.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azimjohn/leetcode/463d9bdf53bfb6f10f1e5c8b233a28107351b82e/top_interview_questions/2_medium/4_backtracking/generate_parentheses/solution.py -------------------------------------------------------------------------------- /top_interview_questions/2_medium/4_backtracking/letter_combinations_of_phone_number/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | letters = { 4 | "2": ["a", "b", "c"], 5 | "3": ["d", "e", "f"], 6 | "4": ["g", "h", "i"], 7 | "5": ["j", "k", "l"], 8 | "6": ["m", "n", "o"], 9 | "7": ["p", "q", "r", "s"], 10 | "8": ["t", "u", "v"], 11 | "9": ["w", "x", "y", "z"], 12 | } 13 | 14 | 15 | class Solution: 16 | def letterCombinations(self, digits: str) -> List[str]: 17 | if not digits: 18 | return [] 19 | 20 | result = letters[digits[0]].copy() 21 | for d in digits[1:]: 22 | result = self.multiply(result, letters[d]) 23 | 24 | return result 25 | 26 | def multiply(self, list1: List[str], list2: List[str]) -> List[str]: 27 | result = [] 28 | 29 | for l1 in list1: 30 | for l2 in list2: 31 | result.append(l1 + l2) 32 | 33 | return result 34 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/4_backtracking/permutations/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | # Todo: solve with iteratively 5 | class Solution: 6 | def __init__(self): 7 | self.memo = {} 8 | 9 | def permute(self, nums: List[int]) -> List[List[int]]: 10 | length = len(nums) 11 | 12 | if length == 1: 13 | return [nums] 14 | 15 | if length == 2: 16 | return [nums, nums[::-1]] 17 | 18 | nums_set = frozenset(nums) 19 | if nums_set in self.memo: 20 | return self.memo[nums_set] 21 | 22 | permuted = [] 23 | for i, num in enumerate(nums): 24 | permutes = self.permute(nums[:i] + nums[i + 1:]) 25 | for permute in permutes: 26 | permuted.append([num] + permute) 27 | 28 | self.memo[nums_set] = permuted 29 | return permuted 30 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/4_backtracking/subsets/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def subsets(self, nums: List[int]) -> List[List[int]]: 6 | subsets_ = [[]] 7 | 8 | for num in nums: 9 | subset = [sub + [num] for sub in subsets_] 10 | subsets_.extend(subset) 11 | 12 | return subsets_ 13 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/4_backtracking/word_search/solution.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azimjohn/leetcode/463d9bdf53bfb6f10f1e5c8b233a28107351b82e/top_interview_questions/2_medium/4_backtracking/word_search/solution.py -------------------------------------------------------------------------------- /top_interview_questions/2_medium/5_sorting_and_searching/find_peak_element/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | 5 | } 6 | 7 | func findPeakElement(nums []int) int { 8 | left := 0 9 | right := len(nums) - 1 10 | 11 | for left < right { 12 | mid := (left + right) / 2 13 | if nums[mid] > nums[mid+1] { 14 | right = mid 15 | } else { 16 | left = mid + 1 17 | } 18 | } 19 | 20 | return left 21 | } 22 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/5_sorting_and_searching/find_peak_element/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def findPeakElement(self, nums: List[int]) -> int: 6 | left = 0 7 | right = len(nums) - 1 8 | 9 | while left < right: 10 | mid = (left + right) // 2 11 | if nums[mid] > nums[mid + 1]: 12 | right = mid 13 | else: 14 | left = mid + 1 15 | 16 | return left 17 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/5_sorting_and_searching/kth_largest_element_in_an_array/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func main() { 4 | 5 | } 6 | 7 | type IntHeap []int 8 | 9 | func (h IntHeap) Len() int { return len(h) } 10 | func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] } 11 | func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } 12 | 13 | func findKthLargest(nums []int, k int) int { 14 | h := IntHeap{} 15 | copy(h, nums) 16 | // heap.Fix(h) 17 | // heap.Pop() // k-1 times 18 | // return head.Pop() 19 | 20 | return 0 21 | } 22 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/5_sorting_and_searching/kth_largest_element_in_an_array/solution.py: -------------------------------------------------------------------------------- 1 | import heapq 2 | from typing import List 3 | 4 | 5 | class Solution: 6 | def findKthLargest(self, nums: List[int], k: int) -> int: 7 | return heapq.nlargest(k, nums)[-1] 8 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/5_sorting_and_searching/merge_intervals/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | ) 7 | 8 | func main() { 9 | fmt.Println(merge( 10 | [][]int{ 11 | {1, 3}, {2, 6}, {8, 10}, {15, 18}, 12 | }, 13 | )) // expected [[1,6],[8,10],[15,18]] 14 | } 15 | 16 | func merge(intervals [][]int) [][]int { 17 | var merged [][]int 18 | 19 | sort.Slice(intervals, func(i, j int) bool { 20 | return intervals[i][0] < intervals[j][0] 21 | }) 22 | 23 | for _, interval := range intervals { 24 | length := len(merged) 25 | if len(merged) == 0 || merged[length-1][1] < interval[0] { 26 | merged = append(merged, interval) 27 | } else { 28 | merged[length-1][1] = max( 29 | merged[length-1][1], 30 | interval[1], 31 | ) 32 | } 33 | } 34 | 35 | return merged 36 | } 37 | 38 | func max(a, b int) int { 39 | if a > b { 40 | return a 41 | } 42 | 43 | return b 44 | } 45 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/5_sorting_and_searching/merge_intervals/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def merge(self, intervals: List[List[int]]) -> List[List[int]]: 3 | intervals.sort(key=lambda x: x[0]) 4 | merged = [] 5 | 6 | for interval in intervals: 7 | if not merged or merged[-1][1] < interval[0]: 8 | merged.append(interval) 9 | else: 10 | merged[-1][1] = max(merged[-1][1], interval[1]) 11 | 12 | return merged 13 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/5_sorting_and_searching/search_a_2d_matrix_ii/solution.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azimjohn/leetcode/463d9bdf53bfb6f10f1e5c8b233a28107351b82e/top_interview_questions/2_medium/5_sorting_and_searching/search_a_2d_matrix_ii/solution.py -------------------------------------------------------------------------------- /top_interview_questions/2_medium/5_sorting_and_searching/search_for_a_range/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | # todo: use binary search 5 | class Solution: 6 | def searchRange(self, nums: List[int], target: int) -> List[int]: 7 | left_start, right_start = -1, -1 8 | 9 | for i, num in enumerate(nums): 10 | if num == target: 11 | left_start = i 12 | break 13 | 14 | for i, num in enumerate(reversed(nums)): 15 | if num == target: 16 | right_start = len(nums) - i - 1 17 | break 18 | 19 | return [left_start, right_start] 20 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/5_sorting_and_searching/search_in_rotated_sorted_array/solution.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azimjohn/leetcode/463d9bdf53bfb6f10f1e5c8b233a28107351b82e/top_interview_questions/2_medium/5_sorting_and_searching/search_in_rotated_sorted_array/solution.py -------------------------------------------------------------------------------- /top_interview_questions/2_medium/5_sorting_and_searching/sort_colors/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | # todo: solve with O(n) 5 | class Solution: 6 | def sortColors(self, nums: List[int]) -> None: 7 | """ 8 | Do not return anything, modify nums in-place instead. 9 | """ 10 | nums.sort() 11 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/5_sorting_and_searching/top_k_frequent_elements/solution.py: -------------------------------------------------------------------------------- 1 | from collections import Counter 2 | from typing import List 3 | 4 | 5 | class Solution: 6 | def topKFrequent(self, nums: List[int], k: int) -> List[int]: 7 | counter = Counter(nums) 8 | most_common = counter.most_common(k) 9 | 10 | return [element[0] for element in most_common] 11 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/6_dynamic_programming/coin_change/solution.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azimjohn/leetcode/463d9bdf53bfb6f10f1e5c8b233a28107351b82e/top_interview_questions/2_medium/6_dynamic_programming/coin_change/solution.py -------------------------------------------------------------------------------- /top_interview_questions/2_medium/6_dynamic_programming/jump_game/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def canJump(self, nums: List[int]) -> bool: 6 | if len(nums) == 1: 7 | return True 8 | 9 | if nums[0] == 0: 10 | return False 11 | 12 | jumps = nums[0] 13 | 14 | for num in nums[1:-1]: 15 | jumps = max(num, jumps - 1) 16 | if jumps <= 0: 17 | return False 18 | 19 | return True 20 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/6_dynamic_programming/longest_increasing_subsequence/solution.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azimjohn/leetcode/463d9bdf53bfb6f10f1e5c8b233a28107351b82e/top_interview_questions/2_medium/6_dynamic_programming/longest_increasing_subsequence/solution.py -------------------------------------------------------------------------------- /top_interview_questions/2_medium/6_dynamic_programming/unique_paths/solution.py: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/problems/unique-paths/ 2 | 3 | 4 | # todo: use DP 5 | class Solution: 6 | def __init__(self): 7 | self.cache = {} 8 | 9 | def uniquePaths(self, m: int, n: int) -> int: 10 | if (m, n) in self.cache: 11 | return self.cache[(m, n)] 12 | 13 | if n == 0 or m == 0: 14 | return 0 15 | 16 | if [m, n] in [[1, 1], [1, 2], [2, 1]]: 17 | return 1 18 | 19 | result = self.uniquePaths(m, n - 1) + self.uniquePaths(m - 1, n) 20 | 21 | self.cache[(m, n)] = result 22 | 23 | return result 24 | 25 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/7_design/insert_delete_get_random_O(1)/solution.go: -------------------------------------------------------------------------------- 1 | import "math/rand" 2 | 3 | type RandomizedSet struct { 4 | hashMap map[int]int 5 | list []int 6 | } 7 | 8 | 9 | /** Initialize your data structure here. */ 10 | func Constructor() RandomizedSet { 11 | return RandomizedSet{map[int]int{}, []int{}} 12 | } 13 | 14 | 15 | /** Inserts a value to the set. Returns true if the set did not already contain the specified element. */ 16 | func (r *RandomizedSet) Insert(val int) bool { 17 | _, exists := r.hashMap[val] 18 | if !exists { 19 | r.hashMap[val] = len(r.list) 20 | r.list = append(r.list, val) 21 | 22 | return true 23 | } 24 | return false 25 | } 26 | 27 | 28 | /** Removes a value from the set. Returns true if the set contained the specified element. */ 29 | func (r *RandomizedSet) Remove(val int) bool { 30 | index, exists := r.hashMap[val] 31 | if exists { 32 | length := len(r.list) 33 | 34 | delete(r.hashMap, val) 35 | r.list[index] = r.list[length-1] 36 | lastVal := r.list[length-1] 37 | r.list = r.list[:length-1] // pop - O(1) ? 38 | 39 | if val != lastVal{ 40 | r.hashMap[lastVal] = index 41 | } 42 | 43 | return true 44 | } 45 | return false 46 | } 47 | 48 | 49 | /** Get a random element from the set. */ 50 | func (r *RandomizedSet) GetRandom() int { 51 | length := len(r.list) 52 | return r.list[rand.Intn(length)] 53 | } 54 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/7_design/insert_delete_get_random_O(1)/solution.py: -------------------------------------------------------------------------------- 1 | import random 2 | 3 | 4 | class RandomizedSet: 5 | 6 | def __init__(self): 7 | """ 8 | Initialize your data structure here. 9 | """ 10 | self.dict = dict() 11 | self.list = list() 12 | 13 | def insert(self, val: int) -> bool: 14 | """ 15 | Inserts a value to the set. Returns true if the set did not already contain the specified element. 16 | """ 17 | if val not in self.dict: 18 | self.dict[val] = len(self.list) 19 | self.list.append(val) 20 | 21 | return True 22 | 23 | return False 24 | 25 | def remove(self, val: int) -> bool: 26 | """ 27 | Removes a value from the set. Returns true if the set contained the specified element. 28 | """ 29 | if val in self.dict: 30 | index = self.dict.pop(val) 31 | self.list[index] = self.list[-1] 32 | 33 | last_val = self.list.pop() 34 | if last_val != val: 35 | self.dict[last_val] = index 36 | 37 | return True 38 | 39 | return False 40 | 41 | def getRandom(self) -> int: 42 | """ 43 | Get a random element from the set. 44 | """ 45 | return random.choice(self.list) 46 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/7_design/serialize_deserialize_binary_tree/solution.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azimjohn/leetcode/463d9bdf53bfb6f10f1e5c8b233a28107351b82e/top_interview_questions/2_medium/7_design/serialize_deserialize_binary_tree/solution.py -------------------------------------------------------------------------------- /top_interview_questions/2_medium/8_math/divide_two_integers/solution.py: -------------------------------------------------------------------------------- 1 | import math 2 | 3 | 4 | class Solution: 5 | def divide(self, dividend: int, divisor: int) -> int: 6 | max_int = 2 ** 31 - 1 7 | min_int = -2 ** 31 8 | sign = 1 if dividend * divisor > 0 else -1 9 | dividend, divisor = abs(dividend), abs(divisor) 10 | 11 | result = dividend / divisor 12 | result = sign * math.floor(result) 13 | 14 | if result < min_int or result > max_int: 15 | return max_int 16 | 17 | return result 18 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/8_math/excel_sheet_column_number/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def __init__(self): 3 | self.letters = {} 4 | self.letters_count = 26 5 | self.fill_letters() 6 | 7 | def fill_letters(self): 8 | for i in range(self.letters_count): 9 | self.letters[chr(65 + i)] = i + 1 10 | 11 | def titleToNumber(self, s: str) -> int: 12 | result = 0 13 | 14 | for index, char in enumerate(reversed(s)): 15 | result += (self.letters_count ** index) * self.letters[char] 16 | 17 | return result 18 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/8_math/factorial_trailing_zeroes/solution.py: -------------------------------------------------------------------------------- 1 | # https://leetcode.com/problems/factorial-trailing-zeroes/ 2 | # Zeros are powers of 10s, 10 is made of 5 and 2 3 | 4 | 5 | def trailingZeroes(n): 6 | if n < 5: 7 | return 0 8 | 9 | fives = n // 5 10 | 11 | return fives + trailingZeroes(fives) 12 | 13 | 14 | if __name__ == "__main__": 15 | cases = [ 16 | (3, 0), 17 | (6, 1), 18 | (50, 12), 19 | ] 20 | 21 | for case in cases: 22 | assert trailingZeroes(case[0]) == case[1] 23 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/8_math/fraction_to_recurring_decimal/solution.py: -------------------------------------------------------------------------------- 1 | def pdi_function(number, base: int = 10): 2 | """Perfect digital invariant function.""" 3 | total = 0 4 | while number > 0: 5 | total = total + pow(number % base, 2) 6 | number = number // base 7 | return total 8 | 9 | 10 | def is_happy(number: int) -> bool: 11 | """Determine if the specified number is a happy number.""" 12 | seen_numbers = [] 13 | while number > 1 and number not in seen_numbers: 14 | seen_numbers.append(number) 15 | number = pdi_function(number) 16 | return number == 1 17 | 18 | 19 | class Solution: 20 | def isHappy(self, n: int) -> bool: 21 | return is_happy(n) 22 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/8_math/happy_number/solution.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azimjohn/leetcode/463d9bdf53bfb6f10f1e5c8b233a28107351b82e/top_interview_questions/2_medium/8_math/happy_number/solution.py -------------------------------------------------------------------------------- /top_interview_questions/2_medium/8_math/power_of_x_to_n/solution.py: -------------------------------------------------------------------------------- 1 | # todo: implement with multiplication 2 | class Solution: 3 | def myPow(self, x: float, n: int) -> float: 4 | return x ** n 5 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/8_math/square_root_of_x/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def mySqrt(self, a: int) -> int: 3 | if a == 0: 4 | return 0 5 | 6 | x = a 7 | 8 | for _ in range(25): 9 | x = 0.5 * (x + a / x) 10 | 11 | return int(x) 12 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/9_others/evaluate_reverse_polish_notation/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | func main() { 9 | fmt.Println(evalRPN([]string{"4", "13", "5", "/", "+"})) 10 | } 11 | 12 | type stack []int 13 | 14 | func (s stack) Push(v int) stack { 15 | return append(s, v) 16 | } 17 | 18 | func (s stack) Pop() (stack, int) { 19 | l := len(s) 20 | return s[:l-1], s[l-1] 21 | } 22 | 23 | func evalRPN(tokens []string) int { 24 | var s stack 25 | var operator string 26 | var r, operandOne, operandTwo int 27 | 28 | operators := map[string]bool{ 29 | "+": true, 30 | "-": true, 31 | "*": true, 32 | "/": true, 33 | } 34 | 35 | for _, token := range tokens { 36 | if !operators[token] { 37 | n, _ := strconv.Atoi(token) 38 | s = s.Push(n) 39 | continue 40 | } 41 | 42 | operator = token 43 | s, operandTwo = s.Pop() 44 | s, operandOne = s.Pop() 45 | 46 | switch operator { 47 | case "+": 48 | r = operandOne + operandTwo 49 | case "-": 50 | r = operandOne - operandTwo 51 | case "*": 52 | r = operandOne * operandTwo 53 | case "/": 54 | r = operandOne / operandTwo 55 | } 56 | fmt.Printf("%d%s%d=%d\n", operandOne, operator, operandTwo, r) 57 | s = s.Push(r) 58 | } 59 | 60 | if len(s) > 0 { 61 | s, r = s.Pop() 62 | } 63 | 64 | return r 65 | } 66 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/9_others/evaluate_reverse_polish_notation/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | def evalRPN(self, tokens: List[str]) -> int: 3 | stack = list() 4 | result = None 5 | 6 | for token in tokens: 7 | if token not in ["*", "/", "+", "-"]: 8 | stack.append(token) 9 | continue 10 | 11 | operator = token 12 | operand_two = int(stack.pop()) 13 | operand_one = int(stack.pop()) 14 | 15 | if operator == "+": 16 | result = operand_one + operand_two 17 | elif operator == "-": 18 | result = operand_one - operand_two 19 | elif operator == "*": 20 | result = operand_one * operand_two 21 | elif operator == "/": 22 | result = operand_one / operand_two 23 | 24 | stack.append(int(result)) 25 | 26 | if stack: 27 | return stack.pop() 28 | 29 | return result 30 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/9_others/majority_element/solution.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | ) 7 | 8 | func main() { 9 | fmt.Println(majorityElement([]int{1, 2, 2, 2, 3, 4})) 10 | } 11 | 12 | func majorityElement(nums []int) int { 13 | l := len(nums) 14 | sort.Ints(nums) 15 | 16 | return nums[l/2] 17 | } 18 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/9_others/majority_element/solution.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | 4 | class Solution: 5 | def majorityElement(self, nums: List[int]) -> int: 6 | nums.sort() 7 | length = len(nums) 8 | 9 | return nums[length // 2] 10 | -------------------------------------------------------------------------------- /top_interview_questions/2_medium/9_others/sum_of_two_integers/solution.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azimjohn/leetcode/463d9bdf53bfb6f10f1e5c8b233a28107351b82e/top_interview_questions/2_medium/9_others/sum_of_two_integers/solution.py -------------------------------------------------------------------------------- /top_interview_questions/2_medium/9_others/task_scheduler/solution.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azimjohn/leetcode/463d9bdf53bfb6f10f1e5c8b233a28107351b82e/top_interview_questions/2_medium/9_others/task_scheduler/solution.py --------------------------------------------------------------------------------