├── .gitignore ├── 3sum └── solution.py ├── 3sum_closest └── solution.py ├── 4sum └── solution.py ├── LICENSE ├── README ├── add_binary ├── solution.py ├── solution2.py └── solution3.py ├── add_digits └── solution.py ├── add_two_numbers ├── solution.py └── solution2.py ├── anagrams └── solution.py ├── balanced_binary_tree ├── solution.py └── solution2.py ├── best_time_to_buy_and_sell_stock └── solution.py ├── best_time_to_buy_and_sell_stock_ii └── solution.py ├── best_time_to_buy_and_sell_stock_iii └── solution.py ├── binary_search_tree_iterator └── solution.py ├── binary_tree_inorder_traversal └── solution.py ├── binary_tree_level_order_traversal ├── solution.py └── solution2.py ├── binary_tree_level_order_traversal_ii └── solution.py ├── binary_tree_maximum_path_sum └── solution.py ├── binary_tree_paths └── solution.py ├── binary_tree_postorder_traversal └── solution.py ├── binary_tree_preorder_traversal └── solution.py ├── binary_tree_zigzag_level_order_traversal └── solution.py ├── bitwise_and_of_numbers_range └── solution.py ├── climbing_stairs ├── solution.py └── solution2.py ├── clone_graph ├── solution.py ├── solution2.py └── solution3.py ├── combination_sum └── solution.py ├── combination_sum_ii ├── solution.py └── solution2.py ├── combinations └── solution.py ├── construct_binary_tree_from_inorder_and_postorder_traversal └── solution.py ├── construct_binary_tree_from_preorder_and_inorder_traversal └── solution.py ├── container_with_most_water └── solution.py ├── contains_duplicate └── solution.py ├── contains_duplicate_ii └── solution.py ├── convert_sorted_array_to_binary_search_tree └── solution.py ├── convert_sorted_list_to_binary_search_tree └── solution.py ├── copy_list_with_random_pointer └── solution.py ├── count_and_say └── solution.py ├── count_primes ├── solution.py └── solution2.py ├── course_schedule ├── solution.py ├── solution2.py └── test.txt ├── delete_node_in_a_linked_list └── solution.py ├── different_ways_to_add_parentheses └── solution.py ├── distinct_subsequences ├── solution.py └── solution2.py ├── edit_distance └── solution.py ├── excel_sheet_column_number └── solution.py ├── factorial_trailing_zeroes └── solution.py ├── find_minimum_in_rotated_sorted_array └── solution.py ├── find_minimum_in_rotated_sorted_array_ii └── solution.py ├── find_peak_element └── solution.py ├── first_bad_version └── solution.py ├── first_missing_positive └── solution.py ├── flatten_binary_tree_to_linked_list └── solution.py ├── gas_station └── solution.py ├── generate_parentheses ├── solution.py └── solution2.py ├── gray_code └── solution.py ├── group_anagrams └── solution.py ├── h_index └── solution.py ├── happy_number └── solution.py ├── house_robber └── solution.py ├── house_robber_ii └── solution.py ├── implement_queue_using_stacks └── solution.py ├── implement_stack_using_queues ├── solution.py └── solution2.py ├── implement_strstr ├── solution.py └── solution2.py ├── insertion_sort_list └── solution.py ├── invert_binary_tree └── solution.py ├── isomorphic_strings └── solution.py ├── jump_game ├── solution.py └── solution2.py ├── jump_game_ii ├── solution.py ├── solution2.py └── solution3.py ├── kth_largest_element_in_an_array ├── solution.py └── solution2.py ├── largest_rectangle_in_histogram └── solution.py ├── length_of_last_word ├── solution.py ├── solution2.py └── solution3.py ├── letter_combinations_of_a_phone_number ├── solution.py ├── solution2.py └── solution3.py ├── linked_list_cycle └── solution.py ├── linked_list_cycle_ii └── solution.py ├── longest_common_prefix └── solution.py ├── longest_consecutive_sequence └── solution.py ├── longest_palindromic_substring └── solution.py ├── longest_substring_without_repeating_characters └── solution.py ├── lowest_common_ancestor_of_a_binary_search_tree └── solution.py ├── lowest_common_ancestor_of_a_binary_tree └── solution.py ├── lru_cache ├── solution.py └── solution2.py ├── majority_element ├── solution.py └── solution2.py ├── majority_element_ii └── solution.py ├── makedir.sh ├── maximal_rectangle └── solution.py ├── maximum_depth_of_binary_tree └── solution.py ├── maximum_subarray ├── solution.py ├── solution2.py └── solution3.py ├── merge_intervals └── solution.py ├── merge_k_sorted_lists └── solution.py ├── merge_sorted_array ├── solution.py └── solution2.py ├── merge_two_sorted_lists ├── solution.py └── solution2.py ├── minimum_depth_of_binary_tree ├── solution.py └── solution2.py ├── minimum_path_sum ├── solution.py └── solution2.py ├── minimum_window_substring └── solution.py ├── missing_number ├── solution.py └── solution2.py ├── move_zeroes └── solution.py ├── multiply_strings └── solution.py ├── n-queens └── solution.py ├── n-queens_ii └── solution.py ├── next_permutation └── solution.py ├── number_of_1_bits └── solution.py ├── number_of_islands └── solution.py ├── palindrome_linked_list └── solution.py ├── palindrome_number └── solution.py ├── palindrome_partitioning └── solution.py ├── partition_list └── solution.py ├── pascals_triangle └── solution.py ├── pascals_triangle_ii └── solution.py ├── path_sum └── solution.py ├── path_sum_ii └── solution.py ├── permutations └── solution.py ├── permutations_ii ├── solution.py └── solution2.py ├── plus_one ├── solution.py ├── solution2.py └── solution3.py ├── populating_next_right_pointers_in_each_node └── solution.py ├── populating_next_right_pointers_in_each_node_ii └── solution.py ├── pow(x,_n) ├── solution.py ├── solution2.py └── solution3.py ├── power_of_two └── solution.py ├── product_of_array_except_self ├── solution.py ├── solution2.py ├── solution3.py └── solution4.py ├── recover_binary_search_tree └── solution.py ├── regular_expression_matching └── solution.py ├── remove_duplicates_from_sorted_array └── solution.py ├── remove_duplicates_from_sorted_array_ii └── solution.py ├── remove_duplicates_from_sorted_list └── solution.py ├── remove_duplicates_from_sorted_list_ii ├── solution.py └── solution2.py ├── remove_element └── solution.py ├── remove_linked_list_elements └── solution.py ├── remove_nth_node_from_end_of_list ├── solution.py └── solution2.py ├── restore_ip_addresses └── solution.py ├── reverse_bits └── solution.py ├── reverse_integer └── solution.py ├── reverse_linked_list ├── solution.py └── solution2.py ├── reverse_linked_list_ii └── solution.py ├── reverse_nodes_in_k-group └── solution.py ├── reverse_words_in_a_string └── solution.py ├── roman_to_integer └── solution.py ├── rotate_array └── solution.py ├── rotate_image └── solution.py ├── rotate_list └── solution.py ├── same_tree └── solution.py ├── search_a_2d_matrix └── solution.py ├── search_a_2d_matrix_ii └── solution.py ├── search_for_a_range ├── solution.py └── solution2.py ├── search_in_rotated_sorted_array ├── solution.py └── solution2.py ├── search_in_rotated_sorted_array_ii ├── solution.py └── solution2.py ├── search_insert_position ├── solution.py └── solution2.py ├── set_matrix_zeroes └── solution.py ├── setup.cfg ├── simplify_path └── solution.py ├── single_number └── solution.py ├── single_number_ii ├── solution.py └── solution2.py ├── sort_colors └── solution.py ├── sort_list └── solution.py ├── spiral_matrix_ii └── solution.py ├── sqrt(x) └── solution.py ├── subsets ├── solution.py ├── solution2.py ├── solution3.py └── solution4.py ├── subsets_ii ├── solution.py └── solution2.py ├── sum_root_to_leaf_numbers └── solution.py ├── summary_ranges └── solution.py ├── surrounded_regions └── solution.py ├── swap_nodes_in_pairs ├── solution.py └── solution2.py ├── symmetric_tree └── solution.py ├── trapping_rain_water ├── solution.py └── solution2.py ├── triangle ├── solution.py └── solution2.py ├── two_sum └── solution.py ├── ugly_number └── solution.py ├── unique_binary_search_trees ├── solution.py └── solution2.py ├── unique_binary_search_trees_ii └── solution.py ├── unique_paths └── solution.py ├── unique_paths_ii ├── solution.py └── solution2.py ├── valid_anagram └── solution.py ├── valid_palindrome └── solution.py ├── valid_parentheses └── solution.py ├── valid_sudoku └── solution.py ├── validate_binary_search_tree ├── solution.py ├── solution2.py └── solution3.py ├── word_break ├── solution.py └── solution2.py ├── word_break_ii ├── solution.py └── solution2.py └── word_ladder ├── solution.py └── solution2.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[cod] 2 | .DS_Store 3 | *.swp 4 | -------------------------------------------------------------------------------- /3sum_closest/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an array S of n integers, find three integers in S such that the sum is 3 | closest to a given number, target. Return the sum of the three integers. You 4 | may assume that each input would have exactly one solution. 5 | 6 | For example, given array S = {-1 2 1 -4}, and target = 1. 7 | 8 | The sum that is closest to the target is 2. (-1 + 2 + 1 = 2). 9 | """ 10 | 11 | 12 | class Solution(object): 13 | def threeSumClosest(self, nums, target): 14 | """ 15 | :type nums: List[int] 16 | :type target: int 17 | :rtype: int 18 | """ 19 | nums.sort() 20 | n = len(nums) 21 | res = nums[0] + nums[1] + nums[2] 22 | for i in range(n - 2): 23 | l = i + 1 24 | r = n - 1 25 | while l < r: 26 | s = nums[i] + nums[l] + nums[r] 27 | if abs(s - target) < abs(res - target): 28 | res = s 29 | if s == target: 30 | return s 31 | elif s < target: 32 | l += 1 33 | else: 34 | r -= 1 35 | return res 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Shichao An 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 10 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | LeetCode Python 2 | =============== 3 | 4 | LeetCode problems solved in Python 5 | -------------------------------------------------------------------------------- /add_binary/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given two binary strings, return their sum (also a binary string). 3 | 4 | For example, 5 | a = "11" 6 | b = "1" 7 | Return "100". 8 | """ 9 | 10 | class Solution(object): 11 | def addBinary(self, a, b): 12 | """ 13 | :type a: str 14 | :type b: str 15 | :rtype: str 16 | """ 17 | res = [] 18 | # a is longer than b 19 | if len(a) < len(b): 20 | b, a = a, b 21 | n = len(a) 22 | m = len(b) 23 | c = 0 # Carry bit 24 | r = 0 # Result bit 25 | # i = n - 1 ... 0 26 | for k in range(n): 27 | i = n - 1 - k 28 | if k < m: 29 | j = m - 1 - k 30 | r = (int(a[i]) + int(b[j]) + c) % 2 31 | c = (int(a[i]) + int(b[j]) + c) / 2 32 | else: 33 | r = (int(a[i]) + c) % 2 34 | c = (int(a[i]) + c) / 2 35 | res.insert(0, str(r)) 36 | if c == 1: 37 | res.insert(0, str(c)) 38 | return ''.join(res) 39 | -------------------------------------------------------------------------------- /add_binary/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given two binary strings, return their sum (also a binary string). 3 | 4 | For example, 5 | a = "11" 6 | b = "1" 7 | Return "100". 8 | """ 9 | 10 | class Solution(object): 11 | def addBinary(self, a, b): 12 | """ 13 | :type a: str 14 | :type b: str 15 | :rtype: str 16 | """ 17 | list_a = [int(i) for i in a[::-1]] 18 | list_b = [int(i) for i in b[::-1]] 19 | la = len(list_a) 20 | lb = len(list_b) 21 | # Pad zeroes 22 | if la < lb: 23 | list_a += [0 for i in range(lb - la)] 24 | la = len(list_a) 25 | else: 26 | list_b += [0 for i in range(la - lb)] 27 | lb = len(list_b) 28 | carry = 0 29 | res = [] 30 | for i in range(la): 31 | t = (list_a[i] + list_b[i] + carry) % 2 32 | carry = (list_a[i] + list_b[i] + carry) / 2 33 | res.append(t) 34 | if carry == 1: 35 | res.append(1) 36 | return ''.join([str(d) for d in res[::-1]]) 37 | -------------------------------------------------------------------------------- /add_binary/solution3.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given two binary strings, return their sum (also a binary string). 3 | 4 | For example, 5 | a = "11" 6 | b = "1" 7 | Return "100". 8 | """ 9 | 10 | class Solution(object): 11 | def addBinary(self, a, b): 12 | """ 13 | :type a: str 14 | :type b: str 15 | :rtype: str 16 | """ 17 | a = a[::-1] 18 | b = b[::-1] 19 | m = len(a) 20 | n = len(b) 21 | i = 0 22 | c = 0 23 | res = ['0' for _ in range(max(m, n) + 1)] 24 | while i < m or i < n or c > 0: 25 | tmp = c 26 | if i < m: 27 | tmp += int(a[i]) 28 | if i < n: 29 | tmp += int(b[i]) 30 | bit = tmp % 2 31 | c = tmp / 2 32 | res[i] = str(bit) 33 | i += 1 34 | res = res[::-1] 35 | for i, c in enumerate(res): 36 | if c != '0': 37 | res = res[i:] 38 | break 39 | else: 40 | res = ['0'] 41 | return ''.join(res) 42 | 43 | 44 | s = Solution() 45 | print s.addBinary('11', '1') 46 | print s.addBinary('111', '0010') 47 | -------------------------------------------------------------------------------- /add_digits/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a non-negative integer num, repeatedly add all its digits until the 3 | result has only one digit. 4 | 5 | For example: 6 | 7 | Given num = 38, the process is like: 3 + 8 = 11, 1 + 1 = 2. Since 2 has only 8 | one digit, return it. 9 | 10 | Follow up: 11 | Could you do it without any loop/recursion in O(1) runtime? 12 | """ 13 | 14 | class Solution(object): 15 | def addDigits(self, num): 16 | """ 17 | :type num: int 18 | :rtype: int 19 | """ 20 | while num / 10: 21 | d = 0 22 | while num > 0: 23 | d += num % 10 24 | num /= 10 25 | num = d 26 | return num 27 | 28 | 29 | s = Solution() 30 | print(s.addDigits(38)) 31 | -------------------------------------------------------------------------------- /add_two_numbers/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 | # @return a ListNode 9 | def addTwoNumbers(self, l1, l2): 10 | carry = 0 11 | res = None 12 | res_end = None 13 | while l1 is not None and l2 is not None: 14 | temp = l1.val + l2.val + carry 15 | digit = temp % 10 16 | carry = temp / 10 17 | if res is None: 18 | res = ListNode(digit) 19 | res_end = res 20 | else: 21 | res_end.next = ListNode(digit) 22 | res_end = res_end.next 23 | l1 = l1.next 24 | l2 = l2.next 25 | rem = None 26 | if l1 is not None: 27 | rem = l1 28 | else: 29 | rem = l2 30 | while rem is not None: 31 | temp = rem.val + carry 32 | digit = temp % 10 33 | carry = temp / 10 34 | if res is None: 35 | res = ListNode(digit) 36 | res_end = res 37 | else: 38 | res_end.next = ListNode(digit) 39 | res_end = res_end.next 40 | rem = rem.next 41 | if carry == 1: 42 | res_end.next = ListNode(1) 43 | res_end = res_end.next 44 | return res 45 | -------------------------------------------------------------------------------- /add_two_numbers/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | You are given two linked lists representing two non-negative numbers. The 3 | digits are stored in reverse order and each of their nodes contain a single 4 | digit. Add the two numbers and return it as a linked list. 5 | 6 | Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) 7 | Output: 7 -> 0 -> 8 8 | """ 9 | 10 | # Definition for singly-linked list. 11 | # class ListNode(object): 12 | # def __init__(self, x): 13 | # self.val = x 14 | # self.next = None 15 | 16 | class Solution(object): 17 | def addTwoNumbers(self, l1, l2): 18 | """ 19 | :type l1: ListNode 20 | :type l2: ListNode 21 | :rtype: ListNode 22 | """ 23 | carry = 0 24 | res = None 25 | res_end = None 26 | while l1 is not None or l2 is not None or carry == 1: 27 | temp = 0 28 | if l1 is not None: 29 | temp += l1.val 30 | l1 = l1.next 31 | if l2 is not None: 32 | temp += l2.val 33 | l2 = l2.next 34 | temp += carry 35 | digit = temp % 10 36 | carry = temp / 10 37 | if res is None: 38 | res = ListNode(digit) 39 | res_end = res 40 | else: 41 | res_end.next = ListNode(digit) 42 | res_end = res_end.next 43 | return res 44 | -------------------------------------------------------------------------------- /anagrams/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param strs, a list of strings 3 | # @return a list of strings 4 | def anagrams(self, strs): 5 | d = {} 6 | res = [] 7 | for i, s in enumerate(strs): 8 | key = self.make_key(s) 9 | # First occurence of an anagram 10 | if key not in d: 11 | d[key] = [s] 12 | else: 13 | d[key].append(s) 14 | for key in d: 15 | if len(d[key]) > 1: 16 | res += d[key] 17 | return res 18 | 19 | def make_key(self, s): 20 | """Generate character-frequency key based on s""" 21 | d = {} 22 | res = [] 23 | for c in s: 24 | if c in d: 25 | d[c] += 1 26 | else: 27 | d[c] = 1 28 | # Iterate form 'a' to 'z' 29 | # This make sure the character occurences is ordered 30 | # and thus unique 31 | for i in range(ord('a'), ord('z') + 1): 32 | c = chr(i) 33 | if c in d: 34 | res.append(c) 35 | res.append(str(d[c])) 36 | return ''.join(res) 37 | -------------------------------------------------------------------------------- /balanced_binary_tree/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a binary tree, determine if it is height-balanced. 3 | 4 | For this problem, a height-balanced binary tree is defined as a binary tree in 5 | which the depth of the two subtrees of every node never differ by more than 1. 6 | """ 7 | 8 | # Definition for a binary tree node. 9 | # class TreeNode(object): 10 | # def __init__(self, x): 11 | # self.val = x 12 | # self.left = None 13 | # self.right = None 14 | 15 | class Solution(object): 16 | def isBalanced(self, root): 17 | """ 18 | :type root: TreeNode 19 | :rtype: bool 20 | """ 21 | if root is None: 22 | return True 23 | else: 24 | if self.isBalanced(root.left) and self.isBalanced(root.right): 25 | return abs(self.depth(root.left) - self.depth(root.right)) <= 1 26 | else: 27 | return False 28 | 29 | def depth(self, root): 30 | if root is None: 31 | return -1 32 | else: 33 | return max(self.depth(root.left), self.depth(root.right)) + 1 34 | -------------------------------------------------------------------------------- /balanced_binary_tree/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a binary tree, determine if it is height-balanced. 3 | 4 | For this problem, a height-balanced binary tree is defined as a binary tree in 5 | which the depth of the two subtrees of every node never differ by more than 1. 6 | """ 7 | 8 | # Definition for a binary tree node. 9 | # class TreeNode(object): 10 | # def __init__(self, x): 11 | # self.val = x 12 | # self.left = None 13 | # self.right = None 14 | 15 | class Solution(object): 16 | def isBalanced(self, root): 17 | """ 18 | :type root: TreeNode 19 | :rtype: bool 20 | """ 21 | if root is None: 22 | return True 23 | else: 24 | if self.height(root) != -1: 25 | return True 26 | else: 27 | return False 28 | 29 | def height(self, root): 30 | # Return -1 if not balanced 31 | if root is None: 32 | return 0 33 | else: 34 | left_height = self.height(root.left) 35 | right_height = self.height(root.right) 36 | if left_height == -1 or right_height == -1: 37 | return -1 38 | else: 39 | if abs(left_height - right_height) <= 1: 40 | return max(left_height, right_height) + 1 41 | else: 42 | return -1 43 | -------------------------------------------------------------------------------- /best_time_to_buy_and_sell_stock/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Say you have an array for which the ith element is the price of a given stock 3 | on day i. 4 | 5 | If you were only permitted to complete at most one transaction (ie, buy one 6 | and sell one share of the stock), design an algorithm to find the maximum 7 | profit. 8 | """ 9 | 10 | 11 | class Solution(object): 12 | def maxProfit(self, prices): 13 | """ 14 | :type prices: List[int] 15 | :rtype: int 16 | """ 17 | if not prices: 18 | return 0 19 | max_profit = 0 20 | min_price = prices[0] 21 | for i, p in enumerate(prices): 22 | max_profit = max(max_profit, (p - min_price)) 23 | min_price = min(min_price, p) 24 | return max_profit 25 | -------------------------------------------------------------------------------- /best_time_to_buy_and_sell_stock_ii/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Say you have an array for which the ith element is the price of a given stock 3 | on day i. 4 | 5 | Design an algorithm to find the maximum profit. You may complete as many 6 | transactions as you like (ie, buy one and sell one share of the stock multiple 7 | times). However, you may not engage in multiple transactions at the 8 | same time (ie, you must sell the stock before you buy again). 9 | """ 10 | 11 | 12 | class Solution(object): 13 | def maxProfit(self, prices): 14 | """ 15 | :type prices: List[int] 16 | :rtype: int 17 | """ 18 | if not prices: 19 | return 0 20 | max_profit = 0 21 | for i in range(1, len(prices)): 22 | if prices[i] > prices[i - 1]: 23 | max_profit += prices[i] - prices[i - 1] 24 | return max_profit 25 | -------------------------------------------------------------------------------- /best_time_to_buy_and_sell_stock_iii/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Say you have an array for which the ith element is the price of a given stock 3 | on day i. 4 | 5 | Design an algorithm to find the maximum profit. You may complete at most two 6 | transactions. 7 | 8 | Note: 9 | You may not engage in multiple transactions at the same time (ie, you must 10 | sell the stock before you buy again). 11 | """ 12 | 13 | 14 | class Solution(object): 15 | def maxProfit(self, prices): 16 | """ 17 | :type prices: List[int] 18 | :rtype: int 19 | """ 20 | if not prices: 21 | return 0 22 | n = len(prices) 23 | m1 = [0] * n 24 | m2 = [0] * n 25 | max_profit1 = 0 26 | min_price1 = prices[0] 27 | max_profit2 = 0 28 | max_price2 = prices[-1] 29 | for i in range(n): 30 | max_profit1 = max(max_profit1, prices[i] - min_price1) 31 | m1[i] = max_profit1 32 | min_price1 = min(min_price1, prices[i]) 33 | for i in range(n): 34 | max_profit2 = max(max_profit2, max_price2 - prices[n - 1 - i]) 35 | m2[n - 1 - i] = max_profit2 36 | max_price2 = max(max_price2, prices[n - 1 - i]) 37 | max_profit = 0 38 | for i in range(n): 39 | max_profit = max(m1[i] + m2[i], max_profit) 40 | return max_profit 41 | -------------------------------------------------------------------------------- /binary_search_tree_iterator/solution.py: -------------------------------------------------------------------------------- 1 | # Definition for a binary tree node 2 | # class TreeNode(object): 3 | # def __init__(self, x): 4 | # self.val = x 5 | # self.left = None 6 | # self.right = None 7 | 8 | class BSTIterator(object): 9 | def __init__(self, root): 10 | self._arr = [] 11 | self._inorder(root) 12 | self._cur = -1 13 | 14 | # @return a boolean, whether we have a next smallest number 15 | def hasNext(self): 16 | if self._arr[self._cur + 1:]: 17 | return True 18 | return False 19 | 20 | # @return an integer, the next smallest number 21 | def next(self): 22 | if self.hasNext(): 23 | self._cur += 1 24 | return self._arr[self._cur] 25 | 26 | def _inorder(self, root): 27 | if root is not None: 28 | if root.left is not None: 29 | self._inorder(root.left) 30 | self._arr.append(root.val) 31 | if root.right is not None: 32 | self._inorder(root.right) 33 | 34 | # Your BSTIterator will be called like this: 35 | # i, v = BSTIterator(root), [] 36 | # while i.hasNext(): v.append(i.next()) 37 | -------------------------------------------------------------------------------- /binary_tree_inorder_traversal/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a binary tree, return the inorder traversal of its nodes' values. 3 | 4 | For example: 5 | Given binary tree {1,#,2,3}, 6 | 1 7 | \ 8 | 2 9 | / 10 | 3 11 | return [1,3,2]. 12 | 13 | Note: Recursive solution is trivial, could you do it iteratively? 14 | """ 15 | 16 | # Definition for a binary tree node. 17 | # class TreeNode(object): 18 | # def __init__(self, x): 19 | # self.val = x 20 | # self.left = None 21 | # self.right = None 22 | 23 | class Solution(object): 24 | def inorderTraversal(self, root): 25 | """ 26 | :type root: TreeNode 27 | :rtype: List[int] 28 | """ 29 | path = [] 30 | if root is None: 31 | return path 32 | stack = [] 33 | while stack or root is not None: 34 | if root is not None: 35 | stack.append(root) 36 | root = root.left 37 | else: 38 | root = stack.pop() 39 | path.append(root.val) 40 | root = root.right 41 | return path 42 | -------------------------------------------------------------------------------- /binary_tree_level_order_traversal/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a binary tree, return the level order traversal of its nodes' values. 3 | (ie, from left to right, level by level). 4 | 5 | For example: 6 | Given binary tree {3,9,20,#,#,15,7}, 7 | 3 8 | / \ 9 | 9 20 10 | / \ 11 | 15 7 12 | return its level order traversal as: 13 | [ 14 | [3], 15 | [9,20], 16 | [15,7] 17 | ] 18 | """ 19 | 20 | # Definition for a binary tree node. 21 | # class TreeNode(object): 22 | # def __init__(self, x): 23 | # self.val = x 24 | # self.left = None 25 | # self.right = None 26 | 27 | class Solution(object): 28 | def levelOrder(self, root): 29 | """ 30 | :type root: TreeNode 31 | :rtype: List[List[int]] 32 | """ 33 | 34 | res = [] 35 | if root is None: 36 | return res 37 | queue = [] 38 | level = [] 39 | queue.append(root) 40 | queue.append(None) 41 | while queue: 42 | root = queue.pop(0) 43 | if root is None: 44 | res.append(level[:]) 45 | level = [] 46 | if queue: 47 | queue.append(None) 48 | else: 49 | level.append(root.val) 50 | if root.left is not None: 51 | queue.append(root.left) 52 | if root.right is not None: 53 | queue.append(root.right) 54 | return res 55 | -------------------------------------------------------------------------------- /binary_tree_level_order_traversal/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a binary tree, return the level order traversal of its nodes' values. 3 | (ie, from left to right, level by level). 4 | 5 | For example: 6 | Given binary tree {3,9,20,#,#,15,7}, 7 | 3 8 | / \ 9 | 9 20 10 | / \ 11 | 15 7 12 | return its level order traversal as: 13 | [ 14 | [3], 15 | [9,20], 16 | [15,7] 17 | ] 18 | """ 19 | 20 | # Definition for a binary tree node. 21 | # class TreeNode(object): 22 | # def __init__(self, x): 23 | # self.val = x 24 | # self.left = None 25 | # self.right = None 26 | 27 | class Solution(object): 28 | def levelOrder(self, root): 29 | """ 30 | :type root: TreeNode 31 | :rtype: List[List[int]] 32 | """ 33 | res = [] 34 | if root is None: 35 | return res 36 | queue = [] 37 | queue.append(root) 38 | while queue: 39 | n = len(queue) 40 | level = [] 41 | for i in range(n): 42 | root = queue.pop(0) 43 | if root.left is not None: 44 | queue.append(root.left) 45 | if root.right is not None: 46 | queue.append(root.right) 47 | level.append(root.val) 48 | res.append(level[:]) 49 | return res 50 | -------------------------------------------------------------------------------- /binary_tree_maximum_path_sum/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a binary tree, find the maximum path sum. 3 | 4 | The path may start and end at any node in the tree. 5 | 6 | For example: 7 | Given the below binary tree, 8 | 9 | 1 10 | / \ 11 | 2 3 12 | Return 6. 13 | """ 14 | 15 | # Definition for a binary tree node. 16 | # class TreeNode(object): 17 | # def __init__(self, x): 18 | # self.val = x 19 | # self.left = None 20 | # self.right = None 21 | 22 | class Solution(object): 23 | def maxPathSum(self, root): 24 | """ 25 | :type root: TreeNode 26 | :rtype: int 27 | """ 28 | max_res = [None] 29 | res = self.max_sum(root, max_res) 30 | return max(res, max_res[0]) 31 | 32 | def max_sum(self, root, max_res): 33 | if root is None: 34 | return 0 35 | else: 36 | left_max = self.max_sum(root.left, max_res) 37 | right_max = self.max_sum(root.right, max_res) 38 | root_max = max(root.val, 39 | root.val + left_max, 40 | root.val + right_max) 41 | if max_res[0] is not None: 42 | max_res[0] = max(max_res[0], 43 | root_max, 44 | root.val + left_max + right_max) 45 | else: 46 | max_res[0] = max(root_max, root.val + left_max + right_max) 47 | return root_max 48 | -------------------------------------------------------------------------------- /binary_tree_paths/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a binary tree, return all root-to-leaf paths. 3 | 4 | For example, given the following binary tree: 5 | 6 | 1 7 | / \ 8 | 2 3 9 | \ 10 | 5 11 | All root-to-leaf paths are: 12 | 13 | ["1->2->5", "1->3"] 14 | """ 15 | 16 | # Definition for a binary tree node. 17 | # class TreeNode(object): 18 | # def __init__(self, x): 19 | # self.val = x 20 | # self.left = None 21 | # self.right = None 22 | 23 | class Solution(object): 24 | def binaryTreePaths(self, root): 25 | """ 26 | :type root: TreeNode 27 | :rtype: List[str] 28 | """ 29 | res = [] 30 | cand = [] 31 | self.binary_tree_paths(root, cand, res) 32 | return res 33 | 34 | def binary_tree_paths(self, root, cand, res): 35 | if root is None: 36 | return 37 | else: 38 | cand.append(root.val) 39 | if root.left is None and root.right is None: 40 | p = '->'.join(map(str, cand)) 41 | res.append(p) 42 | self.binary_tree_paths(root.left, cand, res) 43 | self.binary_tree_paths(root.right, cand, res) 44 | cand.pop() 45 | -------------------------------------------------------------------------------- /binary_tree_postorder_traversal/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a binary tree, return the postorder traversal of its nodes' values. 3 | 4 | For example: 5 | Given binary tree {1,#,2,3}, 6 | 1 7 | \ 8 | 2 9 | / 10 | 3 11 | return [3,2,1]. 12 | """ 13 | 14 | # Definition for a binary tree node. 15 | # class TreeNode(object): 16 | # def __init__(self, x): 17 | # self.val = x 18 | # self.left = None 19 | # self.right = None 20 | 21 | class Solution(object): 22 | def postorderTraversal(self, root): 23 | """ 24 | :type root: TreeNode 25 | :rtype: List[int] 26 | """ 27 | path = [] 28 | if root is None: 29 | return path 30 | stack1 = [] 31 | stack2 = [] 32 | stack1.append(root) 33 | while stack1: 34 | root = stack1.pop() 35 | stack2.append(root.val) 36 | if root.left is not None: 37 | stack1.append(root.left) 38 | if root.right is not None: 39 | stack1.append(root.right) 40 | while stack2: 41 | path.append(stack2.pop()) 42 | return path 43 | -------------------------------------------------------------------------------- /binary_tree_preorder_traversal/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a binary tree, return the preorder traversal of its nodes' values. 3 | 4 | For example: 5 | Given binary tree {1,#,2,3}, 6 | 1 7 | \ 8 | 2 9 | / 10 | 3 11 | 12 | return [1,2,3]. 13 | 14 | """ 15 | 16 | # Definition for a binary tree node. 17 | # class TreeNode(object): 18 | # def __init__(self, x): 19 | # self.val = x 20 | # self.left = None 21 | # self.right = None 22 | 23 | class Solution(object): 24 | def preorderTraversal(self, root): 25 | """ 26 | :type root: TreeNode 27 | :rtype: List[int] 28 | """ 29 | path = [] 30 | if root is None: 31 | return path 32 | stack = [] 33 | stack.append(root) 34 | while stack: 35 | root = stack.pop() 36 | path.append(root.val) 37 | if root.right is not None: 38 | stack.append(root.right) 39 | if root.left is not None: 40 | stack.append(root.left) 41 | return path 42 | -------------------------------------------------------------------------------- /bitwise_and_of_numbers_range/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a range [m, n] where 0 <= m <= n <= 2147483647, return the bitwise AND 3 | of all numbers in this range, inclusive. 4 | 5 | For example, given the range [5, 7], you should return 4. 6 | """ 7 | 8 | class Solution(object): 9 | def rangeBitwiseAnd(self, m, n): 10 | """ 11 | :type m: int 12 | :type n: int 13 | :rtype: int 14 | """ 15 | shift = 0 16 | while n > m: 17 | shift += 1 18 | m = m >> 1 19 | n = n >> 1 20 | return m << shift 21 | 22 | 23 | s = Solution() 24 | print(s.rangeBitwiseAnd(5, 6)) 25 | print(s.rangeBitwiseAnd(0, 2147483647)) 26 | -------------------------------------------------------------------------------- /climbing_stairs/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | You are climbing a stair case. It takes n steps to reach to the top. 3 | 4 | Each time you can either climb 1 or 2 steps. In how many distinct ways can you 5 | climb to the top? 6 | """ 7 | 8 | class Solution(object): 9 | def climbStairs(self, n): 10 | """ 11 | :type n: int 12 | :rtype: int 13 | """ 14 | if n == 0: 15 | return 1 16 | t = [0] * (n + 1) 17 | t[1] = 1 18 | if n == 1: 19 | return t[1] 20 | t[2] = 2 21 | if n <= 2: 22 | return t[n] 23 | for i in range(3, n + 1): 24 | t[i] = t[i - 1] + t[i - 2] 25 | return t[n] 26 | 27 | 28 | s = Solution() 29 | print(s.climbStairs(0)) 30 | print(s.climbStairs(1)) 31 | print(s.climbStairs(2)) 32 | print(s.climbStairs(3)) 33 | print(s.climbStairs(4)) 34 | -------------------------------------------------------------------------------- /climbing_stairs/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | You are climbing a stair case. It takes n steps to reach to the top. 3 | 4 | Each time you can either climb 1 or 2 steps. In how many distinct ways can you 5 | climb to the top? 6 | """ 7 | 8 | class Solution(object): 9 | def climbStairs(self, n): 10 | """ 11 | :type n: int 12 | :rtype: int 13 | """ 14 | t = [0 for i in range(n + 1)] 15 | return self.climb(n, t) 16 | 17 | def climb(self, n, t): 18 | if n == 0: 19 | return 1 20 | elif n < 0: 21 | return 0 22 | elif t[n] != 0: 23 | return t[n] 24 | else: 25 | t[n] = self.climb(n - 1, t) + self.climb(n - 2, t) 26 | return t[n] 27 | 28 | 29 | s = Solution() 30 | print(s.climbStairs(0)) 31 | print(s.climbStairs(1)) 32 | print(s.climbStairs(2)) 33 | print(s.climbStairs(3)) 34 | print(s.climbStairs(4)) 35 | -------------------------------------------------------------------------------- /clone_graph/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Clone an undirected graph. Each node in the graph contains a label and a list 3 | of its neighbors. 4 | """ 5 | 6 | # Definition for a undirected graph node 7 | # class UndirectedGraphNode(object): 8 | # def __init__(self, x): 9 | # self.label = x 10 | # self.neighbors = [] 11 | 12 | class Solution(object): 13 | def cloneGraph(self, node): 14 | """ 15 | :type node: UndirectedGraphNode 16 | :rtype: UndirectedGraphNode 17 | 18 | BFS 19 | """ 20 | if node is None: 21 | return None 22 | queue = [] 23 | start_cloned_node = UndirectedGraphNode(node.label) 24 | visited = set() 25 | # A dictionary that maps labels to cloned nodes 26 | d = {node: start_cloned_node} 27 | queue.append(node) 28 | while queue: 29 | node = queue.pop(0) 30 | visited.add(node) 31 | cloned_node = d[node] 32 | cloned_neighbors = [] 33 | for neighbor in node.neighbors: 34 | if neighbor not in visited: 35 | queue.append(neighbor) 36 | if neighbor not in d: 37 | cloned_neighbor = UndirectedGraphNode(neighbor.label) 38 | d[neighbor] = cloned_neighbor 39 | else: 40 | cloned_neighbor = d[neighbor] 41 | cloned_neighbors.append(cloned_neighbor) 42 | cloned_node.neighbors = cloned_neighbors 43 | return start_cloned_node 44 | -------------------------------------------------------------------------------- /clone_graph/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Clone an undirected graph. Each node in the graph contains a label and a list 3 | of its neighbors. 4 | """ 5 | 6 | # Definition for a undirected graph node 7 | # class UndirectedGraphNode(object): 8 | # def __init__(self, x): 9 | # self.label = x 10 | # self.neighbors = [] 11 | 12 | class Solution(object): 13 | def cloneGraph(self, node): 14 | """ 15 | :type node: UndirectedGraphNode 16 | :rtype: UndirectedGraphNode 17 | 18 | DFS 19 | """ 20 | if node is None: 21 | return None 22 | self.visited = set() 23 | cloned_node = UndirectedGraphNode(node.label) 24 | self.d = {node: cloned_node} 25 | self.visit(node) 26 | return self.d[node] 27 | 28 | def visit(self, node): 29 | if node not in self.visited: 30 | self.visited.add(node) 31 | cloned_node = self.d[node] 32 | cloned_neighbors = [] 33 | for neighbor in node.neighbors: 34 | if neighbor not in self.d: 35 | cloned_neighbor = UndirectedGraphNode(neighbor.label) 36 | self.d[neighbor] = cloned_neighbor 37 | else: 38 | cloned_neighbor = self.d[neighbor] 39 | cloned_neighbors.append(cloned_neighbor) 40 | self.visit(neighbor) 41 | cloned_node.neighbors = cloned_neighbors 42 | -------------------------------------------------------------------------------- /clone_graph/solution3.py: -------------------------------------------------------------------------------- 1 | """ 2 | Clone an undirected graph. Each node in the graph contains a label and a list 3 | of its neighbors. 4 | """ 5 | 6 | # Definition for a undirected graph node 7 | # class UndirectedGraphNode(object): 8 | # def __init__(self, x): 9 | # self.label = x 10 | # self.neighbors = [] 11 | 12 | class Solution(object): 13 | def cloneGraph(self, node): 14 | """ 15 | :type node: UndirectedGraphNode 16 | :rtype: UndirectedGraphNode 17 | BFS with only a queue and dictionary (used as visited set) 18 | """ 19 | if node is None: 20 | return None 21 | queue = [] 22 | start_node = node 23 | start_cloned_node = UndirectedGraphNode(node.label) 24 | d = {node: start_cloned_node} 25 | queue.append(node) 26 | i = 0 27 | while i < len(queue): 28 | node = queue[i] 29 | i += 1 30 | for neighbor in node.neighbors: 31 | if neighbor not in d: 32 | queue.append(neighbor) 33 | cloned_neighbor = UndirectedGraphNode(neighbor.label) 34 | d[neighbor] = cloned_neighbor 35 | for node in queue: 36 | cloned_node = d[node] 37 | cloned_neighbors = [] 38 | for neighbor in node.neighbors: 39 | cloned_neighbor = d[neighbor] 40 | cloned_neighbors.append(cloned_neighbor) 41 | cloned_node.neighbors = cloned_neighbors 42 | return d[start_node] 43 | -------------------------------------------------------------------------------- /combination_sum/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param candidates, a list of integers 3 | # @param target, integer 4 | # @return a list of lists of integers 5 | def combinationSum(self, candidates, target): 6 | res = [] 7 | cand = [] 8 | candidates.sort() 9 | self.combination_sum(candidates, cand, target, res) 10 | return res 11 | 12 | def combination_sum(self, candidates, cand, target, res): 13 | if target < 0: 14 | return 15 | elif target == 0: 16 | res.append(cand[:]) 17 | else: 18 | for i, c in enumerate(candidates): 19 | cand.append(c) 20 | self.combination_sum(candidates[i:], cand, target - c, res) 21 | cand.pop() 22 | -------------------------------------------------------------------------------- /combination_sum_ii/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param candidates, a list of integers 3 | # @param target, integer 4 | # @return a list of lists of integers 5 | def combinationSum2(self, candidates, target): 6 | candidates.sort() 7 | res = [] 8 | cand = [] 9 | self.combination_sum(candidates, target, cand, res) 10 | return res 11 | 12 | def combination_sum(self, candidates, target, cand, res): 13 | if target == 0: 14 | res.append(cand[:]) 15 | elif target < 0: 16 | return 17 | else: 18 | for i, c in enumerate(candidates): 19 | if i == 0: 20 | prev = c 21 | elif prev == c: 22 | continue 23 | else: 24 | prev = c 25 | cand.append(c) 26 | self.combination_sum(candidates[i + 1:], target - c, cand, res) 27 | cand.pop() 28 | -------------------------------------------------------------------------------- /combination_sum_ii/solution2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param candidates, a list of integers 3 | # @param target, integer 4 | # @return a list of lists of integers 5 | def combinationSum2(self, candidates, target): 6 | candidates.sort() 7 | res = [] 8 | cand = [] 9 | self.combination_sum_aux(candidates, target, cand, res) 10 | return res 11 | 12 | def combination_sum_aux(self, candidates, target, cand, res): 13 | if target == 0: 14 | res.append(cand[:]) 15 | else: 16 | prev = None 17 | for i, c in enumerate(candidates): 18 | if prev is None or prev != c: 19 | if target - c >= 0: 20 | cand.append(c) 21 | self.combination_sum_aux(candidates[i + 1:], 22 | target - c, cand, res) 23 | cand.pop() 24 | prev = c 25 | -------------------------------------------------------------------------------- /combinations/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given two integers n and k, return all possible combinations of k numbers out 3 | of 1 ... n. 4 | 5 | For example, 6 | If n = 4 and k = 2, a solution is: 7 | 8 | [ 9 | [2,4], 10 | [3,4], 11 | [2,3], 12 | [1,2], 13 | [1,3], 14 | [1,4], 15 | ] 16 | """ 17 | 18 | 19 | class Solution(object): 20 | def combine(self, n, k): 21 | """ 22 | :type n: int 23 | :type k: int 24 | :rtype: List[List[int]] 25 | """ 26 | a = range(1, n + 1) 27 | return self.combine_aux(a, k) 28 | 29 | def combine_aux(self, a, k): 30 | if k == 0: 31 | return [[]] 32 | else: 33 | res = [] 34 | for i, e in enumerate(a): 35 | rest_comb = self.combine_aux(a[i + 1:], k - 1) 36 | for comb in rest_comb: 37 | comb.insert(0, e) 38 | res += rest_comb 39 | return res 40 | -------------------------------------------------------------------------------- /construct_binary_tree_from_inorder_and_postorder_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 | class Solution: 9 | # @param inorder, a list of integers 10 | # @param postorder, a list of integers 11 | # @return a tree node 12 | def buildTree(self, inorder, postorder): 13 | if not inorder or not postorder: 14 | return None 15 | else: 16 | d = postorder[-1] 17 | root = TreeNode(d) 18 | i = inorder.index(d) 19 | left = self.buildTree(inorder[:i], postorder[:i]) 20 | right = self.buildTree(inorder[i + 1:], postorder[i:-1]) 21 | root.left = left 22 | root.right = right 23 | return root 24 | -------------------------------------------------------------------------------- /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 | class Solution: 9 | # @param preorder, a list of integers 10 | # @param inorder, a list of integers 11 | # @return a tree node 12 | def buildTree(self, preorder, inorder): 13 | if len(inorder) == 0: 14 | return None 15 | else: 16 | root_val = preorder.pop(0) 17 | root_index = inorder.index(root_val) 18 | left_tree = self.buildTree(preorder, inorder[:root_index]) 19 | right_tree = self.buildTree(preorder, inorder[root_index + 1:]) 20 | root = TreeNode(root_val) 21 | root.left = left_tree 22 | root.right = right_tree 23 | return root 24 | -------------------------------------------------------------------------------- /container_with_most_water/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @return an integer 3 | def maxArea(self, height): 4 | n = len(height) 5 | i = 0 6 | j = n - 1 7 | max_area = 0 8 | while i < j: 9 | max_area = max(max_area, (j - i) * min(height[i], height[j])) 10 | if height[i] <= height[j]: 11 | i += 1 12 | else: 13 | j -= 1 14 | return max_area 15 | -------------------------------------------------------------------------------- /contains_duplicate/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an array of integers, find if the array contains any duplicates. Your 3 | function should return true if any value appears at least twice in the array, 4 | and it should return false if every element is distinct. 5 | """ 6 | 7 | class Solution(object): 8 | def containsDuplicate(self, nums): 9 | """ 10 | :type nums: List[int] 11 | :rtype: bool 12 | """ 13 | d = set() 14 | for i in nums: 15 | if i in d: 16 | return True 17 | else: 18 | d.add(i) 19 | return False 20 | -------------------------------------------------------------------------------- /contains_duplicate_ii/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an array of integers and an integer k, find out whether there are two 3 | distinct indices i and j in the array such that nums[i] = nums[j] and the 4 | difference between i and j is at most k. 5 | """ 6 | 7 | class Solution(object): 8 | def containsNearbyDuplicate(self, nums, k): 9 | """ 10 | :type nums: List[int] 11 | :type k: int 12 | :rtype: bool 13 | """ 14 | d = {} 15 | for i, e in enumerate(nums): 16 | if e in d: 17 | if i - d[e] <= k: 18 | return True 19 | d[e] = i 20 | return False 21 | 22 | 23 | args1 = [[1, 0, 1, 1], 1] 24 | s = Solution() 25 | print(s.containsNearbyDuplicate(*args1)) 26 | -------------------------------------------------------------------------------- /convert_sorted_array_to_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 | class Solution: 9 | # @param num, a list of integers 10 | # @return a tree node 11 | def sortedArrayToBST(self, num): 12 | if not num: 13 | return None 14 | else: 15 | mid = len(num) / 2 16 | left_array = num[:mid] 17 | right_array = num[mid + 1:] 18 | root = TreeNode(num[mid]) 19 | left_tree = self.sortedArrayToBST(left_array) 20 | right_tree = self.sortedArrayToBST(right_array) 21 | root.left = left_tree 22 | root.right = right_tree 23 | return root 24 | -------------------------------------------------------------------------------- /convert_sorted_list_to_binary_search_tree/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a singly linked list where elements are sorted in ascending order, 3 | convert it to a height balanced BST. 4 | """ 5 | # Definition for a binary tree node 6 | # class TreeNode: 7 | # def __init__(self, x): 8 | # self.val = x 9 | # self.left = None 10 | # self.right = None 11 | # 12 | # Definition for singly-linked list. 13 | # class ListNode: 14 | # def __init__(self, x): 15 | # self.val = x 16 | # self.next = None 17 | 18 | class Solution: 19 | # @param head, a list node 20 | # @return a tree node 21 | def sortedListToBST(self, head): 22 | if head is None: 23 | return None 24 | else: 25 | # Get the middle node 26 | slow = head 27 | fast = head 28 | prev = None # Previous node to slow (mid) 29 | while fast.next is not None and fast.next.next is not None: 30 | prev = slow 31 | fast = fast.next.next 32 | slow = slow.next 33 | if head is slow: 34 | head = None 35 | if prev is not None: 36 | prev.next = None 37 | root = TreeNode(slow.val) 38 | left = self.sortedListToBST(head) 39 | right = self.sortedListToBST(slow.next) 40 | root.left = left 41 | root.right = right 42 | return root 43 | -------------------------------------------------------------------------------- /copy_list_with_random_pointer/solution.py: -------------------------------------------------------------------------------- 1 | # Definition for singly-linked list with a random pointer. 2 | # class RandomListNode: 3 | # def __init__(self, x): 4 | # self.label = x 5 | # self.next = None 6 | # self.random = None 7 | 8 | class Solution: 9 | # @param head, a RandomListNode 10 | # @return a RandomListNode 11 | def copyRandomList(self, head): 12 | if head is None: 13 | return None 14 | h = head 15 | p = h 16 | while p is not None: 17 | next_node = p.next 18 | new_node = RandomListNode(p.label) 19 | # Insert new node to the original list 20 | p.next = new_node 21 | new_node.next = next_node 22 | p = next_node 23 | p = h 24 | while p is not None: 25 | next_node = p.next.next 26 | new_node = p.next 27 | if p.random is not None: 28 | new_node.random = p.random.next 29 | p = next_node 30 | # Split the list 31 | res = None 32 | end = None 33 | p = h 34 | while p is not None: 35 | next_node = p.next.next 36 | new_node = p.next 37 | # Add to new list 38 | if res is None: 39 | res = new_node 40 | end = new_node 41 | else: 42 | end.next = new_node 43 | end = end.next 44 | # Delete new node from old list 45 | p.next = next_node 46 | p = next_node 47 | return res 48 | -------------------------------------------------------------------------------- /count_and_say/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | The count-and-say sequence is the sequence of integers beginning as follows: 3 | 1, 11, 21, 1211, 111221, ... 4 | 5 | 1 is read off as "one 1" or 11. 6 | 11 is read off as "two 1s" or 21. 7 | 21 is read off as "one 2, then one 1" or 1211. 8 | Given an integer n, generate the nth sequence. 9 | 10 | Note: The sequence of integers will be represented as a string. 11 | """ 12 | 13 | 14 | class Solution(object): 15 | def countAndSay(self, n): 16 | """ 17 | :type n: int 18 | :rtype: str 19 | """ 20 | ln = list(str(1)) 21 | for i in range(1, n): 22 | tn = [] 23 | count = 1 24 | prev = None 25 | for c in ln: 26 | if prev == c: 27 | count += 1 28 | if prev is not None and prev != c: 29 | tn.append(str(count)) 30 | tn.append(str(prev)) 31 | count = 1 32 | prev = c 33 | tn.append(str(count)) 34 | tn.append(str(prev)) 35 | ln = tn 36 | return ''.join(ln) 37 | 38 | 39 | s = Solution() 40 | print s.countAndSay(1) 41 | print s.countAndSay(2) 42 | print s.countAndSay(3) 43 | print s.countAndSay(4) 44 | print s.countAndSay(5) 45 | -------------------------------------------------------------------------------- /count_primes/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Description: 3 | 4 | Count the number of prime numbers less than a non-negative number, n. 5 | 6 | Hint: 7 | 8 | Let's start with a isPrime function. To determine if a number is prime, we 9 | need to check if it is not divisible by any number less than n. The runtime 10 | complexity of isPrime function would be O(n) and hence counting the total 11 | prime numbers up to n would be O(n2). Could we do better? 12 | 13 | """ 14 | 15 | class Solution(object): 16 | def countPrimes(self, n): 17 | """ 18 | :type n: int 19 | :rtype: int 20 | """ 21 | res = 0 22 | for i in range(2, n): 23 | if self.is_prime(i): 24 | res += 1 25 | return res 26 | 27 | def is_prime(self, k): 28 | i = 2 29 | while i * i <= k: 30 | if k % i == 0: 31 | return False 32 | i += 1 33 | return True 34 | 35 | 36 | s = Solution() 37 | print(s.countPrimes(500)) 38 | -------------------------------------------------------------------------------- /count_primes/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Description: 3 | 4 | Count the number of prime numbers less than a non-negative number, n. 5 | 6 | 7 | """ 8 | 9 | class Solution(object): 10 | def countPrimes(self, n): 11 | """ 12 | :type n: int 13 | :rtype: int 14 | """ 15 | t = [True for i in range(n)] 16 | i = 2 17 | while i * i < n: 18 | if t[i] is False: 19 | i += 1 20 | continue 21 | j = i * i 22 | while j < n: 23 | t[j] = False 24 | j += i 25 | i += 1 26 | res = 0 27 | for i in range(2, n): 28 | if t[i] is True: 29 | res += 1 30 | return res 31 | 32 | 33 | s = Solution() 34 | print(s.countPrimes(500)) 35 | -------------------------------------------------------------------------------- /delete_node_in_a_linked_list/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Write a function to delete a node (except the tail) in a singly linked list, 3 | given only access to that node. 4 | 5 | Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node 6 | with value 3, the linked list should become 1 -> 2 -> 4 after calling your 7 | function. 8 | """ 9 | 10 | 11 | # Definition for singly-linked list. 12 | # class ListNode(object): 13 | # def __init__(self, x): 14 | # self.val = x 15 | # self.next = None 16 | 17 | class Solution(object): 18 | def deleteNode(self, node): 19 | """ 20 | :type node: ListNode 21 | :rtype: void Do not return anything, modify node in-place instead. 22 | """ 23 | if node.next is not None: 24 | node.val = node.next.val 25 | node.next = node.next.next 26 | -------------------------------------------------------------------------------- /distinct_subsequences/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @return an integer 3 | def numDistinct(self, S, T): 4 | if len(S) < len(T): 5 | return 0 6 | n = len(S) 7 | m = len(T) 8 | t = [0 for i in range(m + 1)] 9 | t[0] = 1 10 | for i in range(1, n + 1): 11 | # j = m ... 1 12 | for k in range(m): 13 | j = m - k 14 | if S[i - 1] == T[j - 1]: 15 | t[j] += t[j - 1] 16 | return t[m] 17 | -------------------------------------------------------------------------------- /distinct_subsequences/solution2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @return an integer 3 | def numDistinct(self, S, T): 4 | m = len(S) 5 | n = len(T) 6 | dp = [[0 for j in range(m + 1)] for i in range(n + 1)] 7 | for j in range(m + 1): 8 | dp[0][j] = 1 9 | for i in range(1, n + 1): 10 | for j in range(1, m + 1): 11 | dp[i][j] = dp[i][j - 1] 12 | if T[i - 1] == S[j - 1]: 13 | dp[i][j] += dp[i - 1][j - 1] 14 | return dp[n][m] 15 | -------------------------------------------------------------------------------- /edit_distance/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @return an integer 3 | def minDistance(self, word1, word2): 4 | n = len(word1) 5 | m = len(word2) 6 | d = [[0 for j in range(m + 1)] for i in range(n + 1)] 7 | for i in range(n + 1): 8 | d[i][0] = i 9 | for j in range(m + 1): 10 | d[0][j] = j 11 | for i in range(1, n + 1): 12 | for j in range(1, m + 1): 13 | if word1[i - 1] == word2[j - 1]: 14 | d[i][j] = d[i - 1][j - 1] 15 | else: 16 | op = min(d[i - 1][j - 1], # Substitute 17 | d[i - 1][j], # Insert 18 | d[i][j - 1]) # Delete 19 | d[i][j] = op + 1 20 | return d[n][m] 21 | -------------------------------------------------------------------------------- /excel_sheet_column_number/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Related to question Excel Sheet Column Title 3 | 4 | Given a column title as appear in an Excel sheet, return its corresponding 5 | column number. 6 | 7 | For example: 8 | 9 | A -> 1 10 | B -> 2 11 | C -> 3 12 | ... 13 | Z -> 26 14 | AA -> 27 15 | AB -> 28 16 | AZ -> 26 + 26 = 52 17 | BA -> 52 + 1 = 53 18 | """ 19 | 20 | class Solution(object): 21 | def titleToNumber(self, s): 22 | """ 23 | :type s: str 24 | :rtype: int 25 | """ 26 | d = {} 27 | res = 0 28 | for i, k in enumerate(range(ord('A'), ord('Z') + 1), start=1): 29 | d[chr(k)] = i 30 | j = 0 31 | for c in s[::-1]: 32 | res += d[c] * (26 ** j) 33 | j += 1 34 | return res 35 | 36 | 37 | s = Solution() 38 | print s.titleToNumber('A') 39 | print s.titleToNumber('B') 40 | print s.titleToNumber('AA') 41 | print s.titleToNumber('BA') 42 | print s.titleToNumber('AAA') 43 | -------------------------------------------------------------------------------- /factorial_trailing_zeroes/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an integer n, return the number of trailing zeroes in n!. 3 | 4 | Note: Your solution should be in logarithmic time complexity. 5 | """ 6 | 7 | class Solution(object): 8 | def trailingZeroes(self, n): 9 | """ 10 | :type n: int 11 | :rtype: int 12 | """ 13 | res = 0 14 | i = 5 15 | while n / i >= 1: 16 | res += n / i 17 | i *= 5 18 | return res 19 | -------------------------------------------------------------------------------- /find_minimum_in_rotated_sorted_array/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Suppose a sorted array is rotated at some pivot unknown to you beforehand. 3 | 4 | (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). 5 | 6 | Find the minimum element. 7 | 8 | You may assume no duplicate exists in the array. 9 | """ 10 | 11 | class Solution(object): 12 | def findMin(self, nums): 13 | """ 14 | :type nums: List[int] 15 | :rtype: int 16 | """ 17 | n = len(nums) 18 | left = 0 19 | right = n - 1 20 | if n == 1 or nums[left] < nums[right]: 21 | return nums[0] 22 | while left <= right: 23 | mid = left + (right - left) / 2 24 | if mid > 0 and nums[mid - 1] > nums[mid]: 25 | return nums[mid] 26 | # The minimum element is in the right side 27 | elif nums[mid] > nums[right]: 28 | left = mid + 1 29 | # The minimum element is in the left side 30 | else: 31 | right = mid - 1 32 | 33 | 34 | a1 = [4, 5, 6, 7, 0, 1, 2] 35 | s = Solution() 36 | print(s.findMin(a1)) 37 | -------------------------------------------------------------------------------- /find_peak_element/solution.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | A peak element is an element that is greater than its neighbors. 4 | 5 | Given an input array where num[i] ≠ num[i+1], find a peak element and return 6 | its index. 7 | 8 | The array may contain multiple peaks, in that case return the index to any one 9 | of the peaks is fine. 10 | 11 | You may imagine that num[-1] = num[n] = -∞. 12 | 13 | For example, in array [1, 2, 3, 1], 3 is a peak element and your function 14 | should return the index number 2. 15 | 16 | Note: 17 | Your solution should be in logarithmic complexity. 18 | """ 19 | 20 | class Solution(object): 21 | def findPeakElement(self, nums): 22 | """ 23 | :type nums: List[int] 24 | :rtype: int 25 | """ 26 | n = len(nums) 27 | left = 0 28 | right = n - 1 29 | if n == 1: 30 | return 0 31 | while left <= right: 32 | mid = left + (right - left) / 2 33 | if mid == 0 and nums[mid] > nums[mid + 1]: 34 | return mid 35 | elif mid == n - 1 and nums[mid] > nums[mid - 1]: 36 | return mid 37 | elif nums[mid - 1] < nums[mid] > nums[mid + 1]: 38 | return mid 39 | elif mid > 0 and nums[mid - 1] > nums[mid]: 40 | right = mid - 1 41 | else: 42 | left = mid + 1 43 | return mid 44 | 45 | a1 = [1, 2] 46 | a2 = [1, 2, 1] 47 | s = Solution() 48 | print(s.findPeakElement(a1)) 49 | print(s.findPeakElement(a2)) 50 | -------------------------------------------------------------------------------- /first_bad_version/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | You are a product manager and currently leading a team to develop a new 3 | product. Unfortunately, the latest version of your product fails the quality 4 | check. Since each version is developed based on the previous version, all the 5 | versions after a bad version are also bad. 6 | 7 | Suppose you have n versions [1, 2, ..., n] and you want to find out the first 8 | bad one, which causes all the following ones to be bad. 9 | 10 | You are given an API bool isBadVersion(version) which will return whether 11 | version is bad. Implement a function to find the first bad version. You should 12 | minimize the number of calls to the API. 13 | """ 14 | 15 | # The isBadVersion API is already defined for you. 16 | # @param version, an integer 17 | # @return a bool 18 | # def isBadVersion(version): 19 | 20 | class Solution(object): 21 | def firstBadVersion(self, n): 22 | """ 23 | :type n: int 24 | :rtype: int 25 | """ 26 | left = 1 27 | right = n 28 | while left + 1 < right: 29 | mid = left + (right - left) / 2 30 | if isBadVersion(mid): 31 | right = mid 32 | else: 33 | left = mid 34 | if isBadVersion(left): 35 | return left 36 | elif isBadVersion(right): 37 | return right 38 | -------------------------------------------------------------------------------- /first_missing_positive/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an unsorted integer array, find the first missing positive integer. 3 | 4 | For example, 5 | Given [1,2,0] return 3, 6 | and [3,4,-1,1] return 2. 7 | 8 | Your algorithm should run in O(n) time and uses constant space. 9 | """ 10 | 11 | class Solution: 12 | # @param A, a list of integers 13 | # @return an integer 14 | def firstMissingPositive(self, A): 15 | n = len(A) 16 | i = 0 17 | while i < n: 18 | j = A[i] - 1 19 | if A[i] != i + 1 and A[i] >= 1 and A[i] <= n and A[i] != A[j]: 20 | A[i], A[j] = A[j], A[i] 21 | else: 22 | i += 1 23 | for i, e in enumerate(A): 24 | if e != i + 1: 25 | return i + 1 26 | return n + 1 27 | -------------------------------------------------------------------------------- /flatten_binary_tree_to_linked_list/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 | class Solution: 9 | # @param root, a tree node 10 | # @return nothing, do it in place 11 | def flatten(self, root): 12 | if root is None: 13 | return 14 | self.flatten(root.left) 15 | self.flatten(root.right) 16 | left = root.left 17 | right = root.right 18 | if left is not None: 19 | root.right = left 20 | root.left = None 21 | current = left 22 | while current.right is not None: 23 | current = current.right 24 | current.right = right 25 | -------------------------------------------------------------------------------- /gas_station/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param gas, a list of integers 3 | # @param cost, a list of integers 4 | # @return an integer 5 | def canCompleteCircuit(self, gas, cost): 6 | n = len(gas) 7 | t = [0 for i in range(n)] 8 | for i in range(n): 9 | t[i] = gas[i] - cost[i] 10 | res = 0 11 | cs = 0 # Current sum 12 | ts = 0 # Total sum 13 | for i in range(n): 14 | cs += t[i] 15 | ts += t[i] 16 | if cs < 0: 17 | res = i + 1 18 | cs = 0 19 | if ts < 0: 20 | return -1 21 | else: 22 | return res 23 | 24 | def canCompleteCircuit2(self, gas, cost): 25 | # Brute-force 26 | n = len(gas) 27 | for i in range(n): 28 | if gas[i] - cost[i] < 0: 29 | continue 30 | carry = gas[i] - cost[i] 31 | j = (i + 1) % n 32 | flag = True 33 | while j != i % n: 34 | if carry + gas[j] - cost[j] < 0: 35 | flag = False 36 | break 37 | j = (j + 1) % n 38 | if flag: 39 | return i 40 | return -1 41 | 42 | 43 | s = Solution() 44 | print s.canCompleteCircuit2([2, 4], [3, 4]) 45 | -------------------------------------------------------------------------------- /generate_parentheses/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param an integer 3 | # @return a list of string 4 | def generateParenthesis(self, n): 5 | res = [] 6 | cand = '' 7 | self.gp(n, n, cand, res) 8 | return res 9 | 10 | def gp(self, left, right, cand, res): 11 | if left > right or left < 0: 12 | return 13 | elif left == 0 and right == 0: 14 | res.append(cand) 15 | else: 16 | self.gp(left - 1, right, cand + '(', res) 17 | self.gp(left, right - 1, cand + ')', res) 18 | -------------------------------------------------------------------------------- /generate_parentheses/solution2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param an integer 3 | # @return a list of string 4 | def generateParenthesis(self, n): 5 | cand = [] 6 | res = [] 7 | self.generate_paren_aux(n, n, cand, res) 8 | return res 9 | 10 | def generate_paren_aux(self, left, right, cand, res): 11 | if left == 0 and right == 0: 12 | res.append(''.join(cand)) 13 | else: 14 | if left <= right and left > 0: 15 | cand.append('(') 16 | self.generate_paren_aux(left - 1, right, cand, res) 17 | cand.pop() 18 | if left < right and right > 0: 19 | cand.append(')') 20 | self.generate_paren_aux(left, right - 1, cand, res) 21 | cand.pop() 22 | -------------------------------------------------------------------------------- /gray_code/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @return a list of integers 3 | def grayCode(self, n): 4 | m = 1 << n 5 | res = [] 6 | d = [(1 << (i + 1)) / 2 for i in range(n)] 7 | for i in range(m): 8 | num = 0 9 | for j, e in enumerate(d): 10 | if e / (1 << (j + 1)) % 2 == 1: 11 | num += 1 << j 12 | d[j] += 1 13 | res.append(num) 14 | return res 15 | -------------------------------------------------------------------------------- /group_anagrams/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an array of strings, group anagrams together. 3 | 4 | For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"], Return: 5 | 6 | [ 7 | ["ate", "eat","tea"], 8 | ["nat","tan"], 9 | ["bat"] 10 | ] 11 | Note: 12 | For the return value, each inner list's elements must follow the lexicographic 13 | order. 14 | All inputs will be in lower-case. 15 | 16 | """ 17 | 18 | class Solution(object): 19 | def groupAnagrams(self, strs): 20 | """ 21 | :type strs: List[str] 22 | :rtype: List[List[str]] 23 | """ 24 | d = {} 25 | res = [] 26 | for s in strs: 27 | k = self.make_key(s) 28 | if k not in d: 29 | d[k] = [s] 30 | else: 31 | d[k].append(s) 32 | for k in d: 33 | res.append(sorted(d[k])) 34 | return res 35 | 36 | def make_key(self, s): 37 | return ''.join(sorted(s)) 38 | 39 | 40 | s = Solution() 41 | print s.groupAnagrams(["eat", "tea", "tan", "ate", "nat", "bat"]) 42 | -------------------------------------------------------------------------------- /h_index/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an array of citations (each citation is a non-negative integer) of a 3 | researcher, write a function to compute the researcher's h-index. 4 | 5 | According to the definition of h-index on Wikipedia: "A scientist has index h 6 | if h of his/her N papers have at least h citations each, and the other N - h 7 | papers have no more than h citations each." 8 | 9 | For example, given citations = [3, 0, 6, 1, 5], which means the researcher has 10 | 5 papers in total and each of them had received 3, 0, 6, 1, 5 citations 11 | respectively. Since the researcher has 3 papers with at least 3 citations each 12 | and the remaining two with no more than 3 citations each, his h-index is 3. 13 | 14 | Note: If there are several possible values for h, the maximum one is taken as 15 | the h-index. 16 | 17 | [6, 5, 3, 1, 0] 18 | """ 19 | 20 | 21 | class Solution(object): 22 | def hIndex(self, citations): 23 | """ 24 | :type citations: List[int] 25 | :rtype: int 26 | """ 27 | citations.sort(reverse=True) 28 | count = 0 29 | lowest = 0 30 | h = 0 31 | for i, c in enumerate(citations): 32 | lowest = c 33 | count = i + 1 34 | if lowest >= count: 35 | h = count 36 | else: 37 | break 38 | return h 39 | 40 | 41 | a1 = [3, 0, 6, 1, 5] 42 | s = Solution() 43 | print s.hIndex(a1) 44 | -------------------------------------------------------------------------------- /happy_number/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Write an algorithm to determine if a number is "happy". 3 | 4 | A happy number is a number defined by the following process: Starting with any 5 | positive integer, replace the number by the sum of the squares of its digits, 6 | and repeat the process until the number equals 1 (where it will stay), or it 7 | loops endlessly in a cycle which does not include 1. Those numbers for which 8 | this process ends in 1 are happy numbers. 9 | 10 | Example: 19 is a happy number 11 | 12 | 1^2 + 9^2 = 82 13 | 8^2 + 2^2 = 68 14 | 6^2 + 8^2 = 100 15 | 1^2 + 0^2 + 0^2 = 1 16 | """ 17 | 18 | class Solution(object): 19 | def isHappy(self, n): 20 | """ 21 | :type n: int 22 | :rtype: bool 23 | """ 24 | 25 | # Use set d to check endless loop 26 | d = set() 27 | while n not in d: 28 | d.add(n) 29 | t = n 30 | s = 0 # sum 31 | while t != 0: 32 | digit = (t % 10) 33 | s += digit * digit 34 | t /= 10 35 | n = s 36 | if n == 1: 37 | return True 38 | return False 39 | 40 | 41 | s = Solution() 42 | print(s.isHappy(19)) 43 | print(s.isHappy(1)) 44 | print(s.isHappy(20)) 45 | -------------------------------------------------------------------------------- /house_robber/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | You are a professional robber planning to rob houses along a street. Each 3 | house has a certain amount of money stashed, the only constraint stopping you 4 | from robbing each of them is that adjacent houses have security system 5 | connected and it will automatically contact the police if two adjacent houses 6 | were broken into on the same night. 7 | 8 | Given a list of non-negative integers representing the amount of money of each 9 | house, determine the maximum amount of money you can rob tonight without 10 | alerting the police. 11 | """ 12 | 13 | class Solution(object): 14 | def rob(self, nums): 15 | """ 16 | :type nums: List[int] 17 | :rtype: int 18 | """ 19 | n = len(nums) 20 | t = [0 for i in range(n + 1)] 21 | if n == 0: 22 | return t[n] 23 | t[1] = nums[0] 24 | if n <= 1: 25 | return t[n] 26 | t[2] = max(nums[:2]) 27 | for i in range(3, n + 1): 28 | t[i] = max(t[i - 2] + nums[i - 1], t[i - 1]) 29 | return t[n] 30 | 31 | 32 | a1 = [4, 1, 6, 10, 5, 13, 2, 7] 33 | s = Solution() 34 | print(s.rob(a1)) 35 | -------------------------------------------------------------------------------- /house_robber_ii/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Note: This is an extension of House Robber. 3 | 4 | After robbing those houses on that street, the thief has found himself a new 5 | place for his thievery so that he will not get too much attention. This time, 6 | all houses at this place are arranged in a circle. That means the first house 7 | is the neighbor of the last one. Meanwhile, the security system for these 8 | houses remain the same as for those in the previous street. 9 | 10 | Given a list of non-negative integers representing the amount of money of each 11 | house, determine the maximum amount of money you can rob tonight without 12 | alerting the police. 13 | """ 14 | 15 | class Solution(object): 16 | def rob(self, nums): 17 | """ 18 | :type nums: List[int] 19 | :rtype: int 20 | """ 21 | n = len(nums) 22 | if n == 0: 23 | return 0 24 | elif n == 1: 25 | return nums[0] 26 | return max(self.rob_aux(nums, 0), self.rob_aux(nums, 1)) 27 | 28 | def rob_aux(self, nums, left): 29 | n = len(nums) - 1 30 | t = [0 for i in range(n + 1)] 31 | if n == 0: 32 | return t[n] 33 | t[1] = nums[left] 34 | if n <= 1: 35 | return t[n] 36 | t[2] = max(nums[left: left + 2]) 37 | for i in range(3, n + 1): 38 | t[i] = max(t[i - 2] + nums[left + i - 1], t[i - 1]) 39 | return t[n] 40 | 41 | a1 = [1] 42 | a2 = [4, 1, 6, 10, 5, 13, 2, 7] 43 | s = Solution() 44 | print(s.rob(a1)) 45 | print(s.rob(a2)) 46 | -------------------------------------------------------------------------------- /implement_strstr/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Implement strStr(). 3 | 4 | Returns the index of the first occurrence of needle in haystack, or -1 if 5 | needle is not part of haystack. 6 | """ 7 | 8 | class Solution(object): 9 | def strStr(self, haystack, needle): 10 | """ 11 | :type haystack: str 12 | :type needle: str 13 | :rtype: int 14 | """ 15 | n = len(haystack) 16 | m = len(needle) 17 | for i in range(n + 1 - m): 18 | matched = True 19 | for k in range(m): 20 | if haystack[i + k] != needle[k]: 21 | matched = False 22 | break 23 | if matched: 24 | return i 25 | return -1 26 | -------------------------------------------------------------------------------- /implement_strstr/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Implement strStr(). 3 | 4 | Returns the index of the first occurrence of needle in haystack, or -1 if 5 | needle is not part of haystack. 6 | """ 7 | 8 | class Solution(object): 9 | def strStr(self, haystack, needle): 10 | """ 11 | :type haystack: str 12 | :type needle: str 13 | :rtype: int 14 | 15 | needle: | n | 16 | haystack: | n - m | m | 17 | """ 18 | n = len(haystack) 19 | m = len(needle) 20 | for i in range(n + 1 - m): 21 | for k in range(m): 22 | if haystack[i + k] != needle[k]: 23 | break 24 | else: 25 | return i 26 | return -1 27 | -------------------------------------------------------------------------------- /insertion_sort_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 | # @param head, a ListNode 9 | # @return a ListNode 10 | def insertionSortList(self, head): 11 | h = head # h is the temporary head node 12 | # First node of h 13 | if head is not None: 14 | head = head.next 15 | h.next = None 16 | while head is not None: 17 | next_node = head.next 18 | # Insertion sort 19 | current = h 20 | prev = h 21 | while current is not None and head.val > current.val: 22 | prev = current 23 | current = current.next 24 | # head is smaller than the head node of h 25 | # Insert head to the beginning of h 26 | if prev == current: 27 | head.next = h 28 | h = head 29 | # Insert head to the middle or end of h 30 | else: 31 | prev.next = head 32 | head.next = current 33 | head = next_node 34 | return h 35 | -------------------------------------------------------------------------------- /invert_binary_tree/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Invert a binary tree. 3 | 4 | 4 5 | / \ 6 | 2 7 7 | / \ / \ 8 | 1 3 6 9 9 | to 10 | 4 11 | / \ 12 | 7 2 13 | / \ / \ 14 | 9 6 3 1 15 | 16 | """ 17 | 18 | # Definition for a binary tree node. 19 | # class TreeNode(object): 20 | # def __init__(self, x): 21 | # self.val = x 22 | # self.left = None 23 | # self.right = None 24 | 25 | class Solution(object): 26 | def invertTree(self, root): 27 | """ 28 | :type root: TreeNode 29 | :rtype: TreeNode 30 | """ 31 | if root is None: 32 | return None 33 | else: 34 | left = self.invertTree(root.left) 35 | right = self.invertTree(root.right) 36 | root.left = right 37 | root.right = left 38 | return root 39 | -------------------------------------------------------------------------------- /isomorphic_strings/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given two strings s and t, determine if they are isomorphic. 3 | 4 | Two strings are isomorphic if the characters in s can be replaced to get t. 5 | 6 | All occurrences of a character must be replaced with another character while 7 | preserving the order of characters. No two characters may map to the same 8 | character but a character may map to itself. 9 | 10 | For example, 11 | Given "egg", "add", return true. 12 | 13 | Given "foo", "bar", return false. 14 | 15 | Given "paper", "title", return true. 16 | 17 | Note: 18 | You may assume both s and t have the same length. 19 | """ 20 | 21 | class Solution(object): 22 | def isIsomorphic(self, s, t): 23 | """ 24 | :type s: str 25 | :type t: str 26 | :rtype: bool 27 | """ 28 | d = {} 29 | for i, c in enumerate(s): 30 | if c not in d: 31 | d[c] = t[i] 32 | else: 33 | if d[c] != t[i]: 34 | return False 35 | d = {} 36 | for i, c in enumerate(t): 37 | if c not in d: 38 | d[c] = s[i] 39 | else: 40 | if d[c] != s[i]: 41 | return False 42 | return True 43 | 44 | 45 | s = Solution() 46 | f = s.isIsomorphic 47 | print(f('ab', 'aa')) 48 | print(f('egg', 'add')) 49 | print(f('foo', 'bar')) 50 | print(f('paper', 'title')) 51 | -------------------------------------------------------------------------------- /jump_game/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an array of non-negative integers, you are initially positioned at the 3 | first index of the array. 4 | 5 | Each element in the array represents your maximum jump length at that 6 | position. 7 | 8 | Determine if you are able to reach the last index. 9 | 10 | For example: 11 | A = [2,3,1,1,4], return true. 12 | 13 | A = [3,2,1,0,4], return false. 14 | """ 15 | 16 | class Solution: 17 | # @param A, a list of integers 18 | # @return a boolean 19 | def canJump(self, A): 20 | n = len(A) 21 | if n == 1: 22 | return True 23 | t = 0 # Number of remaining steps 24 | for i in range(1, n): 25 | # t is max number of steps that remained if reaching A[i] 26 | t = max(t, A[i - 1]) - 1 27 | if t < 0: 28 | return False 29 | return True 30 | -------------------------------------------------------------------------------- /jump_game/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an array of non-negative integers, you are initially positioned at the 3 | first index of the array. 4 | 5 | Each element in the array represents your maximum jump length at that 6 | position. 7 | 8 | Determine if you are able to reach the last index. 9 | 10 | For example: 11 | A = [2,3,1,1,4], return true. 12 | 13 | A = [3,2,1,0,4], return false. 14 | """ 15 | 16 | class Solution: 17 | # @param A, a list of integers 18 | # @return a boolean 19 | def canJump(self, A): 20 | n = len(A) 21 | if n == 1: 22 | return True 23 | # d[i] is the max index A[i] can reach in A 24 | d = [i + A[i] for i in range(n)] 25 | reach = n - 1 26 | for i in range(1, n): 27 | # j is from n - 1 to 0 28 | j = n - 1 - i 29 | if d[j] >= reach: 30 | reach = j 31 | return reach == 0 32 | -------------------------------------------------------------------------------- /jump_game_ii/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an array of non-negative integers, you are initially positioned at the 3 | first index of the array. 4 | 5 | Each element in the array represents your maximum jump length at that 6 | position. 7 | 8 | Your goal is to reach the last index in the minimum number of jumps. 9 | 10 | For example: 11 | Given array A = [2,3,1,1,4] 12 | 13 | The minimum number of jumps to reach the last index is 2. (Jump 1 step from 14 | index 0 to 1, then 3 steps to the last index.) 15 | """ 16 | 17 | class Solution: 18 | def jump(self, nums): 19 | """ 20 | :type nums: List[int] 21 | :rtype: int 22 | """ 23 | n = len(nums) 24 | if n == 1: 25 | return 0 26 | start = 1 27 | end = nums[0] # `end` is nums[start - 1] 28 | res = 1 # At least one step if len(nums) > 1 29 | reached = False 30 | while end < n - 1: 31 | res += 1 32 | max_end = end # `end` for the next loop 33 | for i in range(start, end + 1): 34 | if i + nums[i] > max_end: 35 | max_end = i + nums[i] 36 | reached = True 37 | if not reached: 38 | return -1 39 | reached = False 40 | start = end + 1 41 | end = max_end 42 | return res 43 | 44 | 45 | s = Solution() 46 | a1 = [2, 3, 1, 1, 4] 47 | a2 = [3, 2, 1, 0, 4] 48 | print s.jump(a1) 49 | print s.jump(a2) 50 | -------------------------------------------------------------------------------- /jump_game_ii/solution3.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an array of non-negative integers, you are initially positioned at the 3 | first index of the array. 4 | 5 | Each element in the array represents your maximum jump length at that 6 | position. 7 | 8 | Your goal is to reach the last index in the minimum number of jumps. 9 | 10 | For example: 11 | Given array A = [2,3,1,1,4] 12 | 13 | The minimum number of jumps to reach the last index is 2. (Jump 1 step from 14 | index 0 to 1, then 3 steps to the last index.) 15 | """ 16 | 17 | class Solution(object): 18 | def jump(self, nums): 19 | """ 20 | :type nums: List[int] 21 | :rtype: int 22 | 23 | Time Limit Exceeded 24 | """ 25 | n = len(nums) 26 | # t[i] means mininum number of jumps to nums[i] 27 | t = [-1 for i in range(n)] 28 | t[0] = 0 29 | if n == 1: 30 | return 1 31 | for i in range(n): 32 | steps = nums[i] 33 | end = min(i + steps, n - 1) 34 | for j in range(i + 1, end + 1): 35 | if t[j] == -1: 36 | t[j] = t[i] + 1 37 | else: 38 | t[j] = min(t[i] + 1, t[j]) 39 | return t[-1] 40 | 41 | 42 | a1 = [2, 3, 1, 1, 4] 43 | s = Solution() 44 | print(s.jump(a1)) 45 | -------------------------------------------------------------------------------- /kth_largest_element_in_an_array/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Find the kth largest element in an unsorted array. Note that it is the kth 3 | largest element in the sorted order, not the kth distinct element. 4 | 5 | For example, 6 | Given [3,2,1,5,6,4] and k = 2, return 5. 7 | 8 | Note: 9 | You may assume k is always valid, 1 <= k <= array's length 10 | """ 11 | 12 | import heapq 13 | 14 | class Solution(object): 15 | def findKthLargest(self, nums, k): 16 | """ 17 | :type nums: List[int] 18 | :type k: int 19 | :rtype: int 20 | """ 21 | h = [] 22 | for e in nums: 23 | heapq.heappush(h, (-e, e)) 24 | for i in range(k): 25 | w, e = heapq.heappop(h) 26 | if i == k - 1: 27 | return e 28 | 29 | 30 | a1 = [3, 2, 1, 5, 6, 4] 31 | s = Solution() 32 | res = s.findKthLargest(a1, 2) 33 | print(res) 34 | -------------------------------------------------------------------------------- /largest_rectangle_in_histogram/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param height, a list of integer 3 | # @return an integer 4 | def largestRectangleArea(self, height): 5 | if not height: 6 | return 0 7 | if len(height) == 1: 8 | return height[0] 9 | stack = [] # The bottom element in the stack is the lowest 10 | max_area = 0 11 | n = len(height) 12 | for i in range(n + 1): 13 | while stack and (i == n or height[stack[-1]] > height[i]): 14 | h = height[stack.pop()] 15 | if stack: 16 | w = i - stack[-1] - 1 17 | else: 18 | w = i 19 | max_area = max(max_area, h * w) 20 | stack.append(i) 21 | return max_area 22 | -------------------------------------------------------------------------------- /length_of_last_word/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a string s consists of upper/lower-case alphabets and empty space 3 | characters ' ', return the length of last word in the string. 4 | 5 | If the last word does not exist, return 0. 6 | 7 | Note: A word is defined as a character sequence consists of non-space 8 | characters only. 9 | 10 | For example, Given s = "Hello World", 11 | return 5. 12 | """ 13 | 14 | class Solution(object): 15 | def lengthOfLastWord(self, s): 16 | """ 17 | :type s: str 18 | :rtype: int 19 | """ 20 | n = len(s) 21 | i = n - 1 22 | while i >= 0 and s[i].isspace(): 23 | i -= 1 24 | res = 0 25 | while i >= 0 and not s[i].isspace(): 26 | res += 1 27 | i -= 1 28 | return res 29 | -------------------------------------------------------------------------------- /length_of_last_word/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a string s consists of upper/lower-case alphabets and empty space 3 | characters ' ', return the length of last word in the string. 4 | 5 | If the last word does not exist, return 0. 6 | 7 | Note: A word is defined as a character sequence consists of non-space 8 | characters only. 9 | 10 | For example, Given s = "Hello World", 11 | return 5. 12 | """ 13 | 14 | class Solution(object): 15 | def lengthOfLastWord(self, s): 16 | """ 17 | :type s: str 18 | :rtype: int 19 | """ 20 | n = len(s) 21 | p = n - 1 22 | right = -1 23 | while p >= 0: 24 | if right == -1 and s[p] != ' ': 25 | right = p 26 | elif right >= 0 and s[p] == ' ': 27 | return right - p 28 | p -= 1 29 | if right >= 0: 30 | return right + 1 31 | else: 32 | return 0 33 | -------------------------------------------------------------------------------- /length_of_last_word/solution3.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a string s consists of upper/lower-case alphabets and empty space 3 | characters ' ', return the length of last word in the string. 4 | 5 | If the last word does not exist, return 0. 6 | 7 | Note: A word is defined as a character sequence consists of non-space 8 | characters only. 9 | 10 | For example, Given s = "Hello World", 11 | return 5. 12 | """ 13 | 14 | class Solution(object): 15 | def lengthOfLastWord(self, s): 16 | """ 17 | :type s: str 18 | :rtype: int 19 | """ 20 | n = len(s) 21 | i = n - 1 22 | res = 0 23 | while i >= 0: 24 | if s[i] != ' ': 25 | res += 1 26 | else: 27 | if res != 0: 28 | break 29 | i -= 1 30 | return res 31 | -------------------------------------------------------------------------------- /letter_combinations_of_a_phone_number/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @return a list of strings, [s1, s2] 3 | def letterCombinations(self, digits): 4 | d = { 5 | '2': 'abc', 6 | '3': 'def', 7 | '4': 'ghi', 8 | '5': 'jkl', 9 | '6': 'mno', 10 | '7': 'pqrs', 11 | '8': 'tuv', 12 | '9': 'wxyz', 13 | } 14 | return self.combinations(digits, 0, d) 15 | 16 | def combinations(self, digits, i, d): 17 | if i == len(digits): 18 | return [''] 19 | else: 20 | res = [] 21 | rest_combs = self.combinations(digits, i + 1, d) 22 | for comb in rest_combs: 23 | number = digits[i] 24 | letters = d[number] 25 | for letter in letters: 26 | res.append(letter + comb) 27 | return res 28 | -------------------------------------------------------------------------------- /letter_combinations_of_a_phone_number/solution2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @return a list of strings, [s1, s2] 3 | def letterCombinations(self, digits): 4 | d = { 5 | '2': 'abc', 6 | '3': 'def', 7 | '4': 'ghi', 8 | '5': 'jkl', 9 | '6': 'mno', 10 | '7': 'pqrs', 11 | '8': 'tuv', 12 | '9': 'wxyz', 13 | } 14 | cand = [] 15 | res = [] 16 | self.letter_combination_aux(digits, d, cand, res) 17 | return res 18 | 19 | def letter_combination_aux(self, digits, d, cand, res): 20 | if not digits: 21 | res.append(''.join(cand)) 22 | else: 23 | digit = digits[0] 24 | if digit in d: 25 | letters = d[digit] 26 | for letter in letters: 27 | cand.append(letter) 28 | self.letter_combination_aux(digits[1:], d, cand, res) 29 | cand.pop() 30 | -------------------------------------------------------------------------------- /letter_combinations_of_a_phone_number/solution3.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @return a list of strings, [s1, s2] 3 | def letterCombinations(self, digits): 4 | d = { 5 | '2': 'abc', 6 | '3': 'def', 7 | '4': 'ghi', 8 | '5': 'jkl', 9 | '6': 'mno', 10 | '7': 'pqrs', 11 | '8': 'tuv', 12 | '9': 'wxyz', 13 | } 14 | cand = [] 15 | res = [] 16 | self.letter_combination_aux(0, digits, d, cand, res) 17 | return res 18 | 19 | def letter_combination_aux(self, i, digits, d, cand, res): 20 | if i == len(digits): 21 | res.append(''.join(cand)) 22 | else: 23 | digit = digits[i] 24 | if digit in d: 25 | letters = d[digit] 26 | for letter in letters: 27 | cand.append(letter) 28 | self.letter_combination_aux(i + 1, digits, d, cand, res) 29 | cand.pop() 30 | -------------------------------------------------------------------------------- /linked_list_cycle/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a linked list, determine if it has a cycle in it. 3 | 4 | Follow up: 5 | Can you solve it without using extra space? 6 | """ 7 | 8 | # Definition for singly-linked list. 9 | # class ListNode(object): 10 | # def __init__(self, x): 11 | # self.val = x 12 | # self.next = None 13 | 14 | class Solution(object): 15 | def hasCycle(self, head): 16 | """ 17 | :type head: ListNode 18 | :rtype: bool 19 | """ 20 | slow = head 21 | fast = head 22 | while fast is not None and fast.next is not None: 23 | slow = slow.next 24 | fast = fast.next.next 25 | if slow == fast: 26 | return True 27 | return False 28 | -------------------------------------------------------------------------------- /linked_list_cycle_ii/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 | # @param head, a ListNode 9 | # @return a list node 10 | def detectCycle(self, head): 11 | if head is None or head.next is None: 12 | return None 13 | slow = head 14 | fast = head 15 | while fast is not None and fast.next is not None: 16 | slow = slow.next 17 | fast = fast.next.next 18 | if fast == slow: 19 | break 20 | # No cycle 21 | if fast is None or fast.next is None: 22 | return None 23 | # Has a cycle, put `slow` back to head 24 | slow = head 25 | while True: 26 | if fast == slow: 27 | break 28 | slow = slow.next 29 | fast = fast.next 30 | return slow 31 | -------------------------------------------------------------------------------- /longest_common_prefix/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Write a function to find the longest common prefix string amongst an array of 3 | strings. 4 | """ 5 | 6 | 7 | class Solution(object): 8 | def longestCommonPrefix(self, strs): 9 | """ 10 | :type strs: List[str] 11 | :rtype: str 12 | """ 13 | if not strs: 14 | return "" 15 | res = strs[0] 16 | for s in strs[1:]: 17 | n = len(s) 18 | for i, c in enumerate(res): 19 | if i >= n or res[i] != s[i]: 20 | res = res[:i] 21 | break 22 | return res 23 | -------------------------------------------------------------------------------- /longest_consecutive_sequence/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param num, a list of integer 3 | # @return an integer 4 | def longestConsecutive(self, num): 5 | if not num: 6 | return 0 7 | d = {} 8 | for e in num: 9 | if e not in d: 10 | d[e] = 1 11 | res = 1 12 | for c in num: 13 | current = 1 14 | if c not in d: 15 | continue 16 | while c - 1 in d: 17 | c -= 1 18 | del d[c] 19 | while c + 1 in d: 20 | c += 1 21 | current += 1 22 | del d[c] 23 | res = max(res, current) 24 | return res 25 | -------------------------------------------------------------------------------- /longest_palindromic_substring/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @return a string 3 | def longestPalindrome(self, s): 4 | n = len(s) 5 | t = [[False for i in range(n)] for j in range(n)] 6 | start = 0 7 | max_len = 1 8 | for i in range(n): 9 | t[i][i] = True 10 | for i in range(n - 1): 11 | j = i + 1 12 | if s[i] == s[j]: 13 | t[i][j] = True 14 | start = i 15 | max_len = 2 16 | for l in range(3, n + 1): 17 | for i in range(n - l + 1): 18 | j = i + l - 1 19 | if s[i] == s[j] and t[i + 1][j - 1]: 20 | t[i][j] = True 21 | start = i 22 | max_len = l 23 | return s[start:start + max_len] 24 | 25 | 26 | a = 'akaa2baakcbbc' 27 | s = Solution() 28 | print s.longestPalindrome(a) 29 | -------------------------------------------------------------------------------- /longest_substring_without_repeating_characters/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @return an integer 3 | def lengthOfLongestSubstring(self, s): 4 | res = 0 5 | cur = 0 6 | d = {} 7 | for i, c in enumerate(s): 8 | if c not in d: 9 | cur += 1 10 | else: 11 | cur = min(i - d[c], cur + 1) 12 | d[c] = i 13 | res = max(res, cur) 14 | return res 15 | -------------------------------------------------------------------------------- /majority_element/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an array of size n, find the majority element. The majority element is 3 | the element that appears more than ⌊ n/2 ⌋ times. 4 | 5 | You may assume that the array is non-empty and the majority element always 6 | exist in the array. 7 | """ 8 | 9 | class Solution(object): 10 | def majorityElement(self, nums): 11 | """ 12 | :type nums: List[int] 13 | :rtype: int 14 | """ 15 | m = len(nums) / 2 16 | d = {} 17 | for k in nums: 18 | if k not in d: 19 | d[k] = 1 20 | else: 21 | d[k] += 1 22 | for k in d: 23 | if d[k] > m: 24 | return k 25 | -------------------------------------------------------------------------------- /majority_element/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an array of size n, find the majority element. The majority element is 3 | the element that appears more than ⌊ n/2 ⌋ times. 4 | 5 | You may assume that the array is non-empty and the majority element always 6 | exist in the array. 7 | """ 8 | 9 | class Solution(object): 10 | def majorityElement(self, nums): 11 | """ 12 | :type nums: List[int] 13 | :rtype: int 14 | """ 15 | count = 0 16 | cand = None 17 | for c in nums: 18 | if count == 0: 19 | cand = c 20 | count += 1 21 | elif cand == c: 22 | count += 1 23 | else: 24 | count -= 1 25 | return cand 26 | -------------------------------------------------------------------------------- /majority_element_ii/solution.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Given an integer array of size n, find all elements that appear more than ⌊ 4 | n/3 ⌋ times. The algorithm should run in linear time and in O(1) space. 5 | """ 6 | 7 | class Solution(object): 8 | def majorityElement(self, nums): 9 | """ 10 | :type nums: List[int] 11 | :rtype: List[int] 12 | """ 13 | cand1 = None 14 | cand2 = None 15 | count1 = 0 16 | count2 = 0 17 | for c in nums: 18 | if cand1 == c: 19 | count1 += 1 20 | elif cand2 == c: 21 | count2 += 1 22 | elif count1 == 0: 23 | cand1 = c 24 | count1 += 1 25 | elif count2 == 0: 26 | cand2 = c 27 | count2 += 1 28 | else: 29 | count1 -= 1 30 | count2 -= 1 31 | count1 = 0 32 | count2 = 0 33 | for c in nums: 34 | if cand1 == c: 35 | count1 += 1 36 | elif cand2 == c: 37 | count2 += 1 38 | m = len(nums) / 3 39 | res = [] 40 | if count1 > m: 41 | res.append(cand1) 42 | if count2 > m: 43 | res.append(cand2) 44 | return res 45 | 46 | 47 | a1 = [8, 8, 7, 7, 7] 48 | a2 = [1, 2] 49 | s = Solution() 50 | print s.majorityElement(a1) 51 | print s.majorityElement(a2) 52 | -------------------------------------------------------------------------------- /makedir.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | USAGE="./makedir.sh title [...]" 4 | 5 | [ "$#" -eq 0 ] && { 6 | echo "$USAGE" 7 | exit 1 8 | } 9 | 10 | SCRIPTDIR=$(dirname "$0") 11 | NEWDIR="$SCRIPTDIR/$(echo "$@" | tr 'A-Z ' 'a-z_' | tr -d "'")" 12 | 13 | [ -d "$NEWDIR" ] && { 14 | echo "This directory already exists" 15 | exit 1 16 | } 17 | 18 | echo "Creating new directory $NEWDIR ..." 19 | mkdir "$NEWDIR" 20 | touch "$NEWDIR/solution.py" 21 | -------------------------------------------------------------------------------- /maximal_rectangle/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param matrix, a list of lists of 1 length string 3 | # @return an integer 4 | def maximalRectangle(self, matrix): 5 | # Make a list of heights 6 | if not matrix: 7 | return 0 8 | n = len(matrix) 9 | if not matrix[0]: 10 | return 0 11 | m = len(matrix[0]) 12 | hist = [[0 for j in range(m)] for i in range(n)] 13 | for i in range(n): 14 | for j in range(m): 15 | if i == 0: 16 | hist[i][j] = int(matrix[i][j]) 17 | else: 18 | if matrix[i][j] == '1': 19 | hist[i][j] = 1 + hist[i - 1][j] 20 | res = 0 21 | for row in hist: 22 | res = max(res, self.max_hist_rect(row)) 23 | return res 24 | 25 | def max_hist_rect(self, heights): 26 | if not heights: 27 | return 0 28 | n = len(heights) 29 | max_area = heights[0] 30 | stack = [] 31 | for i in range(n + 1): 32 | while stack and (i == n or heights[stack[-1]] > heights[i]): 33 | h = heights[stack.pop()] 34 | if stack: 35 | w = i - stack[-1] - 1 36 | else: 37 | w = i 38 | max_area = max(max_area, h * w) 39 | stack.append(i) 40 | return max_area 41 | -------------------------------------------------------------------------------- /maximum_depth_of_binary_tree/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a binary tree, find its maximum depth. 3 | 4 | The maximum depth is the number of nodes along the longest path from the root 5 | node down to the farthest leaf node. 6 | 7 | """ 8 | # Definition for a binary tree node 9 | # class TreeNode: 10 | # def __init__(self, x): 11 | # self.val = x 12 | # self.left = None 13 | # self.right = None 14 | 15 | class Solution: 16 | # @param root, a tree node 17 | # @return an integer 18 | def maxDepth(self, root): 19 | if root is None: 20 | return 0 21 | left_max = self.maxDepth(root.left) 22 | right_max = self.maxDepth(root.right) 23 | return max(left_max, right_max) + 1 24 | -------------------------------------------------------------------------------- /maximum_subarray/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Find the contiguous subarray within an array (containing at least one number) 3 | which has the largest sum. 4 | 5 | For example, given the array [−2,1,−3,4,−1,2,1,−5,4], 6 | the contiguous subarray [4,−1,2,1] has the largest sum = 6. 7 | """ 8 | 9 | class Solution: 10 | # @param A, a list of integers 11 | # @return an integer 12 | def maxSubArray(self, A): 13 | if not A: 14 | msg = 'The input array must contain at least one number.' 15 | raise Exception(msg) 16 | max_sum = A[0] 17 | max_current = max_sum 18 | for i in range(1, len(A)): 19 | max_current = max(A[i], max_current + A[i]) 20 | max_sum = max(max_sum, max_current) 21 | return max_sum 22 | -------------------------------------------------------------------------------- /maximum_subarray/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Find the contiguous subarray within an array (containing at least one number) 3 | which has the largest sum. 4 | 5 | For example, given the array [−2,1,−3,4,−1,2,1,−5,4], 6 | the contiguous subarray [4,−1,2,1] has the largest sum = 6. 7 | """ 8 | 9 | class Solution: 10 | # @param A, a list of integers 11 | # @return an integer 12 | def maxSubArray(self, A): 13 | if not A: 14 | return 0 15 | res = A[0] 16 | cur_sum = A[0] 17 | n = len(A) 18 | for i in range(1, n): 19 | cur_sum = max(cur_sum + A[i], A[i]) 20 | res = max(res, cur_sum) 21 | # If negative sum is not allowed, add the following line: 22 | # if res < 0: return 0 23 | return res 24 | -------------------------------------------------------------------------------- /maximum_subarray/solution3.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Find the contiguous subarray within an array (containing at least one number) 4 | which has the largest sum. 5 | 6 | For example, given the array [−2,1,−3,4,−1,2,1,−5,4], 7 | the contiguous subarray [4,−1,2,1] has the largest sum = 6. 8 | """ 9 | 10 | 11 | class Solution(object): 12 | def maxSubArray(self, nums): 13 | """ 14 | :type nums: List[int] 15 | :rtype: int 16 | """ 17 | # s[i] is sum of nums[0]..nums[i] 18 | # s[i] - s[j] is the sum of nums[j + 1] .. nums[i] 19 | s = [0 for _ in nums] 20 | ts = 0 # temporary sum 21 | for i, c in enumerate(nums): 22 | ts += c 23 | s[i] = ts 24 | min_sum = 0 25 | res = 0 26 | for i, c in enumerate(s): 27 | res = max(res, c - min_sum) 28 | min_sum = min(min_sum, c) 29 | if res == 0: 30 | return max(nums) 31 | return res 32 | 33 | 34 | a1 = [-2, 1, -3, 4, -1, 2, 1, -5, 4] 35 | a2 = [-1, -2, -3, -1] 36 | a3 = [1, 2] 37 | s = Solution() 38 | print s.maxSubArray(a1) 39 | print s.maxSubArray(a2) 40 | print s.maxSubArray(a3) 41 | -------------------------------------------------------------------------------- /merge_intervals/solution.py: -------------------------------------------------------------------------------- 1 | # Definition for an interval. 2 | # class Interval: 3 | # def __init__(self, s=0, e=0): 4 | # self.start = s 5 | # self.end = e 6 | 7 | class Solution: 8 | # @param intervals, a list of Interval 9 | # @return a list of Interval 10 | def merge(self, intervals): 11 | if not intervals: 12 | return [] 13 | n = len(intervals) 14 | if n == 1: 15 | return intervals 16 | else: 17 | # Sort the intervals by start value 18 | intervals.sort(key=lambda x: x.start) 19 | res = [] 20 | res.append(intervals[0]) 21 | cur_end = intervals[0].end 22 | cur_index = 0 23 | for interval in intervals[1:]: 24 | if interval.start <= cur_end: 25 | if interval.end > cur_end: 26 | res[cur_index].end = interval.end 27 | cur_end = interval.end 28 | else: 29 | # Added a non-overlapping interval 30 | res.append(interval) 31 | cur_end = interval.end 32 | cur_index += 1 33 | return res 34 | -------------------------------------------------------------------------------- /merge_sorted_array/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one 3 | sorted array. 4 | 5 | Note: 6 | You may assume that nums1 has enough space (size that is greater or equal to m 7 | + n) to hold additional elements from nums2. The number of elements 8 | initialized in nums1 and nums2 are m and n respectively. 9 | """ 10 | 11 | 12 | class Solution(object): 13 | def merge(self, nums1, m, nums2, n): 14 | """ 15 | :type nums1: List[int] 16 | :type m: int 17 | :type nums2: List[int] 18 | :type n: int 19 | :rtype: void Do not return anything, modify nums1 in-place instead. 20 | """ 21 | i = m - 1 22 | j = n - 1 23 | k = m + n - 1 24 | while i >= 0 and j >= 0: 25 | if nums1[i] > nums2[j]: 26 | nums1[k] = nums1[i] 27 | i -= 1 28 | else: 29 | nums1[k] = nums2[j] 30 | j -= 1 31 | k -= 1 32 | while j >= 0: 33 | nums1[k] = nums2[j] 34 | j -= 1 35 | k -= 1 36 | -------------------------------------------------------------------------------- /merge_sorted_array/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one 3 | sorted array. 4 | 5 | Note: 6 | You may assume that nums1 has enough space (size that is greater or equal to m 7 | + n) to hold additional elements from nums2. The number of elements 8 | initialized in nums1 and nums2 are m and n respectively. 9 | """ 10 | 11 | 12 | class Solution(object): 13 | def merge(self, nums1, m, nums2, n): 14 | """ 15 | :type nums1: List[int] 16 | :type m: int 17 | :type nums2: List[int] 18 | :type n: int 19 | :rtype: void Do not return anything, modify nums1 in-place instead. 20 | """ 21 | i = m - 1 22 | j = n - 1 23 | k = m + n - 1 24 | while k >= 0: 25 | if i >= 0 and j >= 0: 26 | if nums1[i] > nums2[j]: 27 | nums1[k] = nums1[i] 28 | i -= 1 29 | else: 30 | nums1[k] = nums2[j] 31 | j -= 1 32 | elif i < 0: 33 | nums1[k] = nums2[j] 34 | j -= 1 35 | else: 36 | break 37 | k -= 1 38 | -------------------------------------------------------------------------------- /merge_two_sorted_lists/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Merge two sorted linked lists and return it as a new list. The new list should 3 | be made by splicing together the nodes of the first two lists. 4 | """ 5 | 6 | # Definition for singly-linked list. 7 | # class ListNode(object): 8 | # def __init__(self, x): 9 | # self.val = x 10 | # self.next = None 11 | 12 | class Solution(object): 13 | def mergeTwoLists(self, l1, l2): 14 | """ 15 | :type l1: ListNode 16 | :type l2: ListNode 17 | :rtype: ListNode 18 | 19 | No dummy node 20 | """ 21 | res = None 22 | res_end = None 23 | while l1 is not None and l2 is not None: 24 | if l1.val < l2.val: 25 | if res is None: 26 | res = l1 27 | res_end = res 28 | else: 29 | res_end.next = l1 30 | res_end = res_end.next 31 | l1 = l1.next 32 | else: 33 | if res is None: 34 | res = l2 35 | res_end = res 36 | else: 37 | res_end.next = l2 38 | res_end = res_end.next 39 | l2 = l2.next 40 | if l1 is not None: 41 | if res is not None: 42 | res_end.next = l1 43 | else: 44 | res = l1 45 | if l2 is not None: 46 | if res is not None: 47 | res_end.next = l2 48 | else: 49 | res = l2 50 | return res 51 | -------------------------------------------------------------------------------- /merge_two_sorted_lists/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Merge two sorted linked lists and return it as a new list. The new list should 3 | be made by splicing together the nodes of the first two lists. 4 | """ 5 | 6 | # Definition for singly-linked list. 7 | class ListNode(object): 8 | def __init__(self, x): 9 | self.val = x 10 | self.next = None 11 | 12 | class Solution(object): 13 | def mergeTwoLists(self, l1, l2): 14 | """ 15 | :type l1: ListNode 16 | :type l2: ListNode 17 | :rtype: ListNode 18 | 19 | Dummy node 20 | """ 21 | dummy = ListNode(0) 22 | dummy_end = dummy 23 | 24 | while l1 is not None and l2 is not None: 25 | if l1.val < l2.val: 26 | dummy_end.next = l1 27 | l1 = l1.next 28 | else: 29 | dummy_end.next = l2 30 | l2 = l2.next 31 | dummy_end = dummy_end.next 32 | if l1 is not None: 33 | dummy_end.next = l1 34 | else: 35 | dummy_end.next = l2 36 | return dummy.next 37 | -------------------------------------------------------------------------------- /minimum_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 | class Solution: 9 | # @param root, a tree node 10 | # @return an integer 11 | def minDepth(self, root): 12 | if root is None: 13 | return 0 14 | if root.left is None and root.right is None: 15 | return 1 16 | elif root.left is None and root.right is not None: 17 | return self.minDepth(root.right) + 1 18 | elif root.left is not None and root.right is None: 19 | return self.minDepth(root.left) + 1 20 | else: 21 | left_min = self.minDepth(root.left) 22 | right_min = self.minDepth(root.right) 23 | return min(left_min, right_min) + 1 24 | -------------------------------------------------------------------------------- /minimum_depth_of_binary_tree/solution2.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 | # @param root, a tree node 10 | # @return an integer 11 | def minDepth(self, root): 12 | if root is None: 13 | return 0 14 | # BFS 15 | queue1 = [] 16 | queue2 = [] 17 | queue1.append(root) 18 | queue2.append(1) 19 | while queue1: 20 | root = queue1.pop(0) 21 | depth = queue2.pop(0) 22 | if root.left is None and root.right is None: 23 | return depth 24 | if root.left is not None: 25 | queue1.append(root.left) 26 | queue2.append(depth + 1) 27 | if root.right is not None: 28 | queue1.append(root.right) 29 | queue2.append(depth + 1) 30 | -------------------------------------------------------------------------------- /minimum_path_sum/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a m x n grid filled with non-negative numbers, find a path from top left 3 | to bottom right which minimizes the sum of all numbers along its path. 4 | 5 | Note: You can only move either down or right at any point in time. 6 | """ 7 | 8 | class Solution: 9 | # @param grid, a list of lists of integers 10 | # @return an integer 11 | def minPathSum(self, grid): 12 | n = len(grid) 13 | m = len(grid[0]) 14 | t = [[0 for i in range(m)] for j in range(n)] 15 | for i in range(n): 16 | for j in range(m): 17 | if i == 0 and j == 0: 18 | t[i][j] = grid[i][j] 19 | elif i == 0: 20 | t[i][j] = grid[i][j] + t[i][j - 1] 21 | elif j == 0: 22 | t[i][j] = grid[i][j] + t[i - 1][j] 23 | else: 24 | t[i][j] = grid[i][j] + min(t[i - 1][j], t[i][j - 1]) 25 | return t[n - 1][m - 1] 26 | -------------------------------------------------------------------------------- /minimum_path_sum/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a m x n grid filled with non-negative numbers, find a path from top left 3 | to bottom right which minimizes the sum of all numbers along its path. 4 | 5 | Note: You can only move either down or right at any point in time. 6 | """ 7 | 8 | class Solution: 9 | # @param grid, a list of lists of integers 10 | # @return an integer 11 | def minPathSum(self, grid): 12 | n = len(grid) 13 | m = len(grid[0]) 14 | t = [[-1 for i in range(m)] for j in range(n)] 15 | return self.min_path_sum_aux(grid, m - 1, n - 1, t) 16 | 17 | def min_path_sum_aux(self, grid, x, y, t): 18 | if x == 0 and y == 0: 19 | return grid[y][x] 20 | elif t[y][x] != -1: 21 | return t[y][x] 22 | elif x == 0 and y > 0: 23 | t[y][x] = grid[y][x] + self.min_path_sum_aux(grid, x, y - 1, t) 24 | return t[y][x] 25 | elif x > 0 and y == 0: 26 | t[y][x] = grid[y][x] + self.min_path_sum_aux(grid, x - 1, y, t) 27 | return t[y][x] 28 | else: 29 | a = self.min_path_sum_aux(grid, x - 1, y, t) 30 | b = self.min_path_sum_aux(grid, x, y - 1, t) 31 | t[y][x] = grid[y][x] + min(a, b) 32 | return t[y][x] 33 | -------------------------------------------------------------------------------- /minimum_window_substring/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @return a string 3 | def minWindow(self, S, T): 4 | s = S 5 | t = T 6 | d = {} 7 | td = {} 8 | for c in t: 9 | td[c] = td.get(c, 0) + 1 10 | left = 0 11 | right = 0 12 | lefts = [] 13 | rights = [] 14 | for i, c in enumerate(s): 15 | if c in td: 16 | d[c] = d.get(c, 0) + 1 17 | if self.contains(d, td): # Contains all characters 18 | right = i 19 | # Move left pointers 20 | cc = s[left] 21 | while left <= right and (cc not in d or d[cc] > td[cc]): 22 | if cc in d: 23 | d[cc] -= 1 24 | left += 1 25 | cc = s[left] 26 | lefts.append(left) 27 | rights.append(right) 28 | if not lefts: 29 | return '' 30 | res_left = lefts[0] 31 | res_right = rights[0] 32 | n = len(lefts) 33 | for i in range(1, n): 34 | if rights[i] - lefts[i] < res_right - res_left: 35 | res_left = lefts[i] 36 | res_right = rights[i] 37 | return s[res_left:res_right + 1] 38 | 39 | def contains(self, d, td): 40 | for k in td: 41 | if k not in d or d[k] < td[k]: 42 | return False 43 | return True 44 | -------------------------------------------------------------------------------- /missing_number/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find 3 | the one that is missing from the array. 4 | 5 | For example, 6 | Given nums = [0, 1, 3] return 2. 7 | 8 | Note: 9 | Your algorithm should run in linear runtime complexity. Could you implement it 10 | using only constant extra space complexity? 11 | """ 12 | 13 | class Solution(object): 14 | def missingNumber(self, nums): 15 | """ 16 | :type nums: List[int] 17 | :rtype: int 18 | """ 19 | n = len(nums) 20 | s = n * (n + 1) / 2 21 | res = 0 22 | for i in nums: 23 | res += i 24 | return s - res 25 | 26 | s = Solution() 27 | a1 = [0, 1, 3] 28 | print(s.missingNumber(a1)) 29 | -------------------------------------------------------------------------------- /missing_number/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find 3 | the one that is missing from the array. 4 | 5 | For example, 6 | Given nums = [0, 1, 3] return 2. 7 | 8 | Note: 9 | Your algorithm should run in linear runtime complexity. Could you implement it 10 | using only constant extra space complexity? 11 | """ 12 | 13 | # Alternative solution using a method similar to First Missing Positive 14 | 15 | class Solution(object): 16 | def missingNumber(self, nums): 17 | """ 18 | :type nums: List[int] 19 | :rtype: int 20 | """ 21 | n = len(nums) 22 | i = 0 23 | while i < n: 24 | j = nums[i] 25 | if nums[i] != i and j < n: 26 | nums[i], nums[j] = nums[j], nums[i] 27 | else: 28 | i += 1 29 | for i, e in enumerate(nums): 30 | if i != e: 31 | return i 32 | else: 33 | return n 34 | 35 | 36 | a0 = [0] 37 | a1 = [0, 1, 3] 38 | a2 = [3, 0, 1] 39 | a3 = [3, 5, 1, 2, 0] 40 | s = Solution() 41 | print(s.missingNumber(a0)) 42 | print(s.missingNumber(a1)) 43 | print(s.missingNumber(a2)) 44 | print(s.missingNumber(a3)) 45 | -------------------------------------------------------------------------------- /move_zeroes/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an array nums, write a function to move all 0's to the end of it while 3 | maintaining the relative order of the non-zero elements. 4 | 5 | For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums 6 | should be [1, 3, 12, 0, 0]. 7 | 8 | Note: 9 | You must do this in-place without making a copy of the array. 10 | Minimize the total number of operations. 11 | """ 12 | 13 | 14 | class Solution(object): 15 | def moveZeroes(self, nums): 16 | """ 17 | :type nums: List[int] 18 | :rtype: void Do not return anything, modify nums in-place instead. 19 | """ 20 | j = 0 21 | for i, c in enumerate(nums): 22 | if c != 0: 23 | nums[i], nums[j] = nums[j], nums[i] 24 | j += 1 25 | 26 | 27 | a1 = [0, 1, 0, 3, 12] 28 | s = Solution() 29 | s.moveZeroes(a1) 30 | print a1 31 | -------------------------------------------------------------------------------- /multiply_strings/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given two numbers represented as strings, return multiplication of the numbers 3 | as a string. 4 | 5 | Note: The numbers can be arbitrarily large and are non-negative. 6 | """ 7 | 8 | 9 | class Solution(object): 10 | def multiply(self, num1, num2): 11 | """ 12 | :type num1: str 13 | :type num2: str 14 | :rtype: str 15 | """ 16 | a = num1[::-1] 17 | b = num2[::-1] 18 | n = len(a) 19 | m = len(b) 20 | res = ['0' for i in range(n + m)] 21 | for i in range(n): 22 | c = 0 23 | for j in range(m): 24 | tmp = int(a[i]) * int(b[j]) + int(res[i + j]) + c 25 | digit = tmp % 10 26 | res[i + j] = str(digit) 27 | c = tmp / 10 28 | if c > 0: 29 | res[m + i] = str(c) 30 | res = ''.join(res[::-1]) 31 | for i, d in enumerate(res): 32 | if d != '0': 33 | return res[i:] 34 | else: 35 | return '0' 36 | 37 | s = Solution() 38 | 39 | print s.multiply('2', '21') 40 | print s.multiply('83', '3') 41 | -------------------------------------------------------------------------------- /n-queens/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @return a list of lists of string 3 | def solveNQueens(self, n): 4 | self.n = n 5 | res = [] 6 | columns = [-1 for i in range(n)] 7 | self.solve(columns, 0, res) 8 | return res 9 | 10 | def make_string_list(self, columns): 11 | sol = [] # One solution (list of strings) 12 | row = ['.' for i in columns] 13 | for c in columns: 14 | new_row = row[:] 15 | new_row[c] = 'Q' 16 | sol.append(''.join(new_row)) 17 | return sol 18 | 19 | def is_valid(self, columns, row, col): 20 | for r in range(row): 21 | c = columns[r] 22 | if c == col: 23 | return False 24 | if abs(c - col) == row - r: 25 | return False 26 | return True 27 | 28 | def solve(self, columns, row, res): 29 | if row == self.n: 30 | res.append(self.make_string_list(columns)) 31 | else: 32 | for col in range(self.n): 33 | if self.is_valid(columns, row, col): 34 | columns[row] = col 35 | self.solve(columns, row + 1, res) 36 | -------------------------------------------------------------------------------- /n-queens_ii/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @return an integer 3 | def totalNQueens(self, n): 4 | self.res = 0 5 | self.n = n 6 | columns = [-1 for i in range(n)] 7 | self.solve(columns, 0) 8 | return self.res 9 | 10 | def is_valid(self, columns, row, col): 11 | for r in range(row): 12 | c = columns[r] 13 | if c == col: 14 | return False 15 | if abs(c - col) == row - r: 16 | return False 17 | return True 18 | 19 | def solve(self, columns, row): 20 | if row == self.n: 21 | self.res += 1 22 | else: 23 | for col in range(self.n): 24 | if self.is_valid(columns, row, col): 25 | columns[row] = col 26 | self.solve(columns, row + 1) 27 | -------------------------------------------------------------------------------- /next_permutation/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param num, a list of integer 3 | # @return a list of integer 4 | def nextPermutation(self, num): 5 | n = len(num) 6 | k = -1 7 | l = -1 8 | # Find the largest k such that num[k] < num[k + 1] 9 | for i in range(n - 1): 10 | if num[i] < num[i + 1]: 11 | k = i 12 | 13 | # Find the largest l such that num[k] < num[l] (if k exists) 14 | if k >= 0: 15 | for i in range(n): 16 | if num[i] > num[k]: 17 | l = i 18 | # Swap num[l] and num[k] 19 | num[l], num[k] = num[k], num[l] 20 | 21 | # Reverse num[k + 1:] 22 | left = k + 1 23 | right = n - 1 24 | while left < right: 25 | num[left], num[right] = num[right], num[left] 26 | left += 1 27 | right -= 1 28 | return num 29 | 30 | 31 | s = Solution() 32 | print s.nextPermutation([2, 1, 3]) 33 | print s.nextPermutation([1, 2, 3]) 34 | print s.nextPermutation([3, 2, 1]) 35 | -------------------------------------------------------------------------------- /number_of_1_bits/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Write a function that takes an unsigned integer and returns the number of ’1' 3 | bits it has (also known as the Hamming weight). 4 | 5 | For example, the 32-bit integer ’11' has binary representation 6 | 00000000000000000000000000001011, so the function should return 3. 7 | 8 | """ 9 | 10 | class Solution(object): 11 | def hammingWeight(self, n): 12 | """ 13 | :type n: int 14 | :rtype: int 15 | """ 16 | res = 0 17 | while n > 0: 18 | if n & 1 == 1: 19 | res += 1 20 | n >>= 1 21 | return res 22 | -------------------------------------------------------------------------------- /number_of_islands/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param {character[][]} grid 3 | # @return {integer} 4 | def numIslands(self, grid): 5 | self.islands = set() # coordinates of 1s (set of tuples) 6 | res = 0 7 | n = len(grid) 8 | if n == 0: 9 | return 0 10 | m = len(grid[0]) 11 | if m == 0: 12 | return 0 13 | for y in range(n): 14 | for x in range(m): 15 | if grid[y][x] == '1' and (x, y) not in self.islands: 16 | self.probe(grid, x, y, m, n) 17 | res += 1 18 | return res 19 | 20 | def probe(self, grid, x, y, m, n): 21 | """ 22 | Probe right and down 23 | """ 24 | if x >= m or y >= n: 25 | return 26 | elif grid[y][x] == '0': 27 | return 28 | else: 29 | self.islands.add((x, y)) 30 | self.probe(grid, x + 1, y, m, n) 31 | self.probe(grid, x, y + 1, m, n) 32 | 33 | 34 | g1 = [ 35 | list('11000'), 36 | list('11000'), 37 | list('00100'), 38 | list('00011') 39 | ] 40 | for r in g1: 41 | print(r) 42 | s = Solution() 43 | print(s.numIslands(g1)) 44 | print(s.islands) 45 | -------------------------------------------------------------------------------- /palindrome_linked_list/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a singly linked list, determine if it is a palindrome. 3 | 4 | Follow up: 5 | Could you do it in O(n) time and O(1) space? 6 | """ 7 | 8 | # Definition for singly-linked list. 9 | # class ListNode(object): 10 | # def __init__(self, x): 11 | # self.val = x 12 | # self.next = None 13 | 14 | class Solution(object): 15 | def isPalindrome(self, head): 16 | """ 17 | :type head: ListNode 18 | :rtype: bool 19 | """ 20 | -------------------------------------------------------------------------------- /palindrome_number/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @return a boolean 3 | def isPalindrome(self, x): 4 | if x < 0: 5 | return False 6 | num_digit = 0 7 | y = x 8 | while y != 0: 9 | y /= 10 10 | num_digit += 1 11 | if num_digit <= 1: 12 | return True 13 | # Reverse the right half 14 | i = 0 15 | t = 0 16 | while i < num_digit / 2: 17 | t = t * 10 + x % 10 18 | x /= 10 19 | i += 1 20 | # Remove the middle digit if num_digit is odd 21 | if num_digit % 2 == 1: 22 | x /= 10 23 | # Compare t and x 24 | if t == x: 25 | return True 26 | else: 27 | return False 28 | -------------------------------------------------------------------------------- /palindrome_partitioning/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param s, a string 3 | # @return a list of lists of string 4 | def partition(self, s): 5 | res = [] 6 | cand = [] 7 | self.partition_aux(s, cand, res) 8 | return res 9 | 10 | def partition_aux(self, s, cand, res): 11 | if not s: 12 | res.append(cand[:]) 13 | else: 14 | for i, e in enumerate(s): 15 | if self.is_palindrome(s[:i + 1]): 16 | cand.append(s[:i + 1]) 17 | self.partition_aux(s[i + 1:], cand, res) 18 | cand.pop() 19 | 20 | def is_palindrome(self, s): 21 | left = 0 22 | right = len(s) - 1 23 | while left < right: 24 | if s[left] != s[right]: 25 | return False 26 | left += 1 27 | right -= 1 28 | return True 29 | -------------------------------------------------------------------------------- /partition_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 | # @param head, a ListNode 9 | # @param x, an integer 10 | # @return a ListNode 11 | def partition(self, head, x): 12 | if head is None: 13 | return head 14 | large = None 15 | large_end = None 16 | res = None 17 | res_end = None 18 | while head is not None: 19 | next_node = head.next 20 | if head.val >= x: 21 | if large is None: 22 | large = head 23 | large_end = large 24 | else: 25 | large_end.next = head 26 | large_end = large_end.next 27 | else: 28 | if res is None: 29 | res = head 30 | res_end = res 31 | else: 32 | res_end.next = head 33 | res_end = res_end.next 34 | head = next_node 35 | if large_end is not None: 36 | large_end.next = None 37 | if res is not None: 38 | res_end.next = large 39 | else: 40 | res = large 41 | return res 42 | -------------------------------------------------------------------------------- /pascals_triangle/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given numRows, generate the first numRows of Pascal's triangle. 3 | 4 | For example, given numRows = 5, 5 | Return 6 | 7 | [ 8 | [1], 9 | [1,1], 10 | [1,2,1], 11 | [1,3,3,1], 12 | [1,4,6,4,1] 13 | ] 14 | """ 15 | 16 | 17 | class Solution(object): 18 | def generate(self, numRows): 19 | """ 20 | :type numRows: int 21 | :rtype: List[List[int]] 22 | """ 23 | res = [] 24 | if numRows == 0: 25 | return res 26 | res.append([1]) 27 | if numRows == 1: 28 | return res 29 | res.append([1, 1]) 30 | if numRows == 2: 31 | return res 32 | # n is current row index (starting from 0) 33 | for n in range(2, numRows): 34 | cur = [] 35 | for i in range(n + 1): 36 | if i == 0: 37 | cur.append(1) 38 | elif i == n: 39 | cur.append(1) 40 | else: 41 | c = res[n - 1][i - 1] + res[n - 1][i] 42 | cur.append(c) 43 | res.append(cur) 44 | return res 45 | -------------------------------------------------------------------------------- /pascals_triangle_ii/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an index k, return the kth row of the Pascal's triangle. 3 | 4 | For example, given k = 3, 5 | Return [1,3,3,1]. 6 | 7 | 8 | [1,1,1,1,1], 9 | [1,1,1,1,1], 10 | [1,2,1,1,1], 11 | [1,3,3,1,1], 12 | [1,4,6,4,1], 13 | 14 | Note: 15 | Could you optimize your algorithm to use only O(k) extra space? 16 | """ 17 | 18 | class Solution(object): 19 | def getRow(self, rowIndex): 20 | """ 21 | :type rowIndex: int 22 | :rtype: List[int] 23 | """ 24 | res = [1 for i in range(rowIndex + 1)] 25 | for row in range(rowIndex + 1): 26 | for col in range(1, row): 27 | col = row - col 28 | res[col] += res[col - 1] 29 | return res 30 | 31 | s = Solution() 32 | print s.getRow(3) 33 | -------------------------------------------------------------------------------- /path_sum/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 | class Solution: 9 | # @param root, a tree node 10 | # @param sum, an integer 11 | # @return a boolean 12 | def hasPathSum(self, root, sum): 13 | if root is None: 14 | return False 15 | elif root.left is None and root.right is None: 16 | if sum == root.val: 17 | return True 18 | else: 19 | return False 20 | else: 21 | sum -= root.val 22 | return (self.hasPathSum(root.left, sum) 23 | or self.hasPathSum(root.right, sum)) 24 | -------------------------------------------------------------------------------- /path_sum_ii/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 | class Solution: 9 | # @param root, a tree node 10 | # @param sum, an integer 11 | # @return a list of lists of integers 12 | def pathSum(self, root, sum): 13 | if root is None: 14 | return [] 15 | one = [] 16 | res = [] 17 | self.ps(root, sum, one, res) 18 | return res 19 | 20 | def ps(self, root, sum, one, res): 21 | if root is None: 22 | return 23 | elif root.left is None and root.right is None: 24 | if root.val == sum: 25 | one.append(root.val) 26 | res.append(one[:]) 27 | one.pop() 28 | else: 29 | one.append(root.val) 30 | self.ps(root.left, sum - root.val, one, res) 31 | self.ps(root.right, sum - root.val, one, res) 32 | one.pop() 33 | -------------------------------------------------------------------------------- /permutations/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a collection of numbers, return all possible permutations. 3 | 4 | For example, 5 | [1,2,3] have the following permutations: 6 | [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], and [3,2,1]. 7 | 8 | """ 9 | 10 | 11 | class Solution(object): 12 | def permute(self, nums): 13 | """ 14 | :type nums: List[int] 15 | :rtype: List[List[int]] 16 | """ 17 | if not nums: 18 | return [[]] 19 | else: 20 | res = [] 21 | for i, e in enumerate(nums): 22 | rest = nums[:i] + nums[i + 1:] 23 | rest_perms = self.permute(rest) 24 | for perm in rest_perms: 25 | perm.append(e) 26 | res += rest_perms 27 | return res 28 | -------------------------------------------------------------------------------- /permutations_ii/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a collection of numbers that might contain duplicates, return all 3 | possible unique permutations. 4 | 5 | For example, 6 | [1,1,2] have the following unique permutations: 7 | [1,1,2], [1,2,1], and [2,1,1]. 8 | """ 9 | 10 | class Solution(object): 11 | def permuteUnique(self, nums): 12 | """ 13 | :type nums: List[int] 14 | :rtype: List[List[int]] 15 | """ 16 | d = {} 17 | return self.permute(nums, d) 18 | 19 | def permute(self, nums, d): 20 | if not nums: 21 | return [[]] 22 | else: 23 | res = [] 24 | for i, c in enumerate(nums): 25 | if c in d: 26 | continue 27 | else: 28 | d[c] = True 29 | rest_perms = self.permuteUnique(nums[:i] + nums[i + 1:]) 30 | for perm in rest_perms: 31 | perm.insert(0, c) 32 | res += rest_perms 33 | return res 34 | -------------------------------------------------------------------------------- /permutations_ii/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a collection of numbers that might contain duplicates, return all 3 | possible unique permutations. 4 | 5 | For example, 6 | [1,1,2] have the following unique permutations: 7 | [1,1,2], [1,2,1], and [2,1,1]. 8 | """ 9 | 10 | class Solution(object): 11 | def permuteUnique(self, nums): 12 | """ 13 | :type nums: List[int] 14 | :rtype: List[List[int]] 15 | """ 16 | return self.permute(sorted(nums)) 17 | 18 | def permute(self, nums): 19 | if not nums: 20 | return [[]] 21 | else: 22 | res = [] 23 | prev = None 24 | for i, e in enumerate(nums): 25 | if prev is None or prev != e: 26 | rest = nums[:i] + nums[i + 1:] 27 | rest_perms = self.permute(rest) 28 | for perm in rest_perms: 29 | perm.append(e) 30 | res += rest_perms 31 | prev = e 32 | return res 33 | -------------------------------------------------------------------------------- /plus_one/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param digits, a list of integer digits 3 | # @return a list of integer digits 4 | def plusOne(self, digits): 5 | digits.reverse() 6 | res = [] 7 | t = (digits[0] + 1) % 10 8 | carry = (digits[0] + 1) / 10 9 | res.append(t) 10 | for d in digits[1:]: 11 | t = (d + carry) % 10 12 | carry = (d + carry) / 10 13 | res.append(t) 14 | if carry == 1: 15 | res.append(1) 16 | res.reverse() 17 | return res 18 | -------------------------------------------------------------------------------- /plus_one/solution2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param digits, a list of integer digits 3 | # @return a list of integer digits 4 | def plusOne(self, digits): 5 | # In-place version 6 | digits.reverse() 7 | d = digits[0] 8 | digits[0] = (d + 1) % 10 9 | carry = (d + 1) / 10 10 | for i, d in enumerate(digits[1:], 1): 11 | digits[i] = (d + carry) % 10 12 | carry = (d + carry) / 10 13 | if carry == 1: 14 | digits.append(1) 15 | digits.reverse() 16 | return digits 17 | -------------------------------------------------------------------------------- /plus_one/solution3.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a non-negative number represented as an array of digits, plus one to the 3 | number. 4 | 5 | The digits are stored such that the most significant digit is at the head of 6 | the list. 7 | """ 8 | 9 | class Solution(object): 10 | def plusOne(self, digits): 11 | """ 12 | :type digits: List[int] 13 | :rtype: List[int] 14 | """ 15 | digits = digits[::-1] 16 | n = len(digits) 17 | temp = 0 18 | # Treat "plus one" as the initial carry being 1 19 | carry = 1 20 | i = 0 21 | res = [] 22 | while i < n or carry > 0: 23 | temp = 0 24 | if i < n: 25 | temp += digits[i] 26 | if carry > 0: 27 | temp += carry 28 | digit = temp % 10 29 | carry = temp / 10 30 | res.append(digit) 31 | i += 1 32 | return res[::-1] 33 | 34 | a0 = [] 35 | a1 = [3, 3, 5] 36 | a2 = [4, 9, 9] 37 | a3 = [9, 9, 9] 38 | s = Solution() 39 | print s.plusOne(a0) 40 | print s.plusOne(a1) 41 | print s.plusOne(a2) 42 | print s.plusOne(a3) 43 | -------------------------------------------------------------------------------- /populating_next_right_pointers_in_each_node_ii/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 | # self.next = None 8 | 9 | class Solution: 10 | # @param root, a tree node 11 | # @return nothing 12 | def connect(self, root): 13 | head = None # Head node of the next level 14 | prev = None 15 | while root is not None: 16 | # Build the next level of root 17 | while root is not None: 18 | if root.left is not None: 19 | if prev is None: 20 | head = root.left 21 | prev = head 22 | else: 23 | prev.next = root.left 24 | prev = prev.next 25 | if root.right is not None: 26 | if prev is None: 27 | head = root.right 28 | prev = head 29 | else: 30 | prev.next = root.right 31 | prev = prev.next 32 | root = root.next 33 | root = head 34 | head = None 35 | prev = None 36 | -------------------------------------------------------------------------------- /pow(x,_n)/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param x, a float 3 | # @param n, a integer 4 | # @return a float 5 | def pow(self, x, n): 6 | if n == 0: 7 | return 1.0 8 | elif n < 0: 9 | return 1.0 / self.pow(x, -n) 10 | else: 11 | if n % 2 == 0: 12 | return self.pow(x * x, n / 2) 13 | else: 14 | return self.pow(x * x, (n - 1) / 2) * x 15 | -------------------------------------------------------------------------------- /pow(x,_n)/solution2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param x, a float 3 | # @param n, a integer 4 | # @return a float 5 | def pow(self, x, n): 6 | if n == 0: 7 | return 1.0 8 | elif n < 0: 9 | return 1.0 / self.pow(x, -n) 10 | else: 11 | if n % 2 == 0: 12 | r = self.pow(x, n / 2) 13 | return r * r 14 | else: 15 | r = self.pow(x, (n - 1) / 2) 16 | return r * r * x 17 | -------------------------------------------------------------------------------- /pow(x,_n)/solution3.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param x, a float 3 | # @param n, a integer 4 | # @return a float 5 | def pow(self, x, n): 6 | if n == 0: 7 | return 1.0 8 | elif n == 1: 9 | return x 10 | elif n < 0: 11 | return 1.0 / self.pow(x, -n) 12 | else: 13 | return self.pow(x, n / 2) * self.pow(x, n - n / 2) 14 | -------------------------------------------------------------------------------- /power_of_two/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an integer, write a function to determine if it is a power of two. 3 | """ 4 | 5 | class Solution(object): 6 | def isPowerOfTwo(self, n): 7 | """ 8 | :type n: int 9 | :rtype: bool 10 | """ 11 | if n < 1: 12 | return False 13 | return n & (n - 1) == 0 14 | -------------------------------------------------------------------------------- /product_of_array_except_self/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an array of n integers where n > 1, nums, return an array output such 3 | that output[i] is equal to the product of all the elements of nums except 4 | nums[i]. 5 | 6 | Solve it without division and in O(n). 7 | 8 | For example, given [1,2,3,4], return [24,12,8,6]. 9 | 10 | Follow up: 11 | Could you solve it with constant space complexity? (Note: The output array 12 | does not count as extra space for the purpose of space complexity analysis.) 13 | """ 14 | 15 | class Solution(object): 16 | def productExceptSelf(self, nums): 17 | """ 18 | :type nums: List[int] 19 | :rtype: List[int] 20 | 21 | Memory Limit Exceeded 22 | """ 23 | if not nums: 24 | return [] 25 | elif len(nums) == 1: 26 | return [1] 27 | elif len(nums) == 2: 28 | return nums[::-1] 29 | else: 30 | m = 1 31 | rest = nums[1:] 32 | for c in rest: 33 | m *= c 34 | res = [m] 35 | for r in self.productExceptSelf(rest): 36 | res.append(r * nums[0]) 37 | return res 38 | 39 | 40 | a1 = [1, 2, 3] 41 | a2 = [2, 3, 4] 42 | a3 = [1, 2, 3, 4] 43 | a4 = [2, 3, 4, 5] 44 | 45 | s = Solution() 46 | print(s.productExceptSelf(a1)) 47 | print(s.productExceptSelf(a2)) 48 | print(s.productExceptSelf(a3)) 49 | print(s.productExceptSelf(a4)) 50 | -------------------------------------------------------------------------------- /product_of_array_except_self/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an array of n integers where n > 1, nums, return an array output such 3 | that output[i] is equal to the product of all the elements of nums except 4 | nums[i]. 5 | 6 | Solve it without division and in O(n). 7 | 8 | For example, given [1,2,3,4], return [24,12,8,6]. 9 | 10 | Follow up: 11 | Could you solve it with constant space complexity? (Note: The output array 12 | does not count as extra space for the purpose of space complexity analysis.) 13 | """ 14 | 15 | class Solution(object): 16 | def productExceptSelf(self, nums): 17 | """ 18 | :type nums: List[int] 19 | :rtype: List[int] 20 | 21 | Time Limit Exceeded 22 | """ 23 | n = len(nums) 24 | res = [1 for i in range(n)] 25 | # product of nums[0..i - 1] 26 | product = 1 27 | for i in range(1, n): 28 | for j in range(i): 29 | res[j] *= nums[i] 30 | product *= nums[i - 1] 31 | res[i] = product 32 | return res 33 | 34 | 35 | a1 = [1, 2, 3] 36 | a2 = [2, 3, 4] 37 | a3 = [1, 2, 3, 4] 38 | a4 = [2, 3, 4, 5] 39 | 40 | s = Solution() 41 | print(s.productExceptSelf(a1)) 42 | print(s.productExceptSelf(a2)) 43 | print(s.productExceptSelf(a3)) 44 | print(s.productExceptSelf(a4)) 45 | -------------------------------------------------------------------------------- /recover_binary_search_tree/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Two elements of a binary search tree (BST) are swapped by mistake. 3 | 4 | Recover the tree without changing its structure. 5 | 6 | Note: 7 | A solution using O(n) space is pretty straight forward. Could you devise a 8 | constant space solution? 9 | """ 10 | 11 | # Definition for a binary tree node 12 | # class TreeNode: 13 | # def __init__(self, x): 14 | # self.val = x 15 | # self.left = None 16 | # self.right = None 17 | 18 | class Solution: 19 | # @param root, a tree node 20 | # @return a tree node 21 | def recoverTree(self, root): 22 | self.prev = None 23 | self.first = None 24 | self.second = None 25 | self.traverse(root) 26 | self.first.val, self.second.val = self.second.val, self.first.val 27 | return root 28 | 29 | def traverse(self, root): 30 | if root is not None: 31 | self.traverse(root.left) 32 | if self.prev is not None: 33 | if self.first is None and root.val < self.prev.val: 34 | self.first = self.prev 35 | self.second = root 36 | elif self.first is not None and root.val < self.prev.val: 37 | self.second = root 38 | self.prev = root 39 | self.traverse(root.right) 40 | -------------------------------------------------------------------------------- /regular_expression_matching/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @return a boolean 3 | def isMatch(self, s, p): 4 | if not p: 5 | return not s 6 | if not s: 7 | return False 8 | return self.is_match_aux(s, p, 0, 0) 9 | 10 | def is_match_aux(self, s, p, si, pi): 11 | if pi == len(p): 12 | return si == len(s) 13 | # Next char is not * 14 | # pi may be the last char 15 | if pi < len(p) - 1 and p[pi + 1] != '*' or pi == len(p) - 1: 16 | assert p[pi] != '*' 17 | # si must be in bound 18 | is_cur_matched = si < len(s) and (p[pi] == s[si] or p[pi] == '.') 19 | is_next_matched = self.is_match_aux(s, p, si + 1, pi + 1) 20 | return is_cur_matched and is_next_matched 21 | # Next char is * 22 | while si < len(s) and pi < len(p) and (p[pi] == s[si] or p[pi] == '.'): 23 | if self.is_match_aux(s, p, si, pi + 2): 24 | return True 25 | si += 1 26 | return self.is_match_aux(s, p, si, pi + 2) 27 | 28 | 29 | s = Solution() 30 | print s.isMatch("aa", "a") 31 | print s.isMatch("aa", "aa") 32 | print s.isMatch("aaa", "aa") 33 | print s.isMatch("aa", "a*") 34 | print s.isMatch("aa", ".*") 35 | print s.isMatch("ab", ".*") 36 | print s.isMatch("aab", "c*a*b") 37 | -------------------------------------------------------------------------------- /remove_duplicates_from_sorted_array/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param a list of integers 3 | # @return an integer 4 | def removeDuplicates(self, A): 5 | if not A: 6 | return 0 7 | if len(A) == 1: 8 | return 1 9 | j = 0 # Position of last processed non-duplicate 10 | n = len(A) 11 | for i in range(1, n): 12 | if A[i] != A[j]: 13 | A[j + 1] = A[i] 14 | j += 1 15 | return j + 1 16 | -------------------------------------------------------------------------------- /remove_duplicates_from_sorted_array_ii/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param A a list of integers 3 | # @return an integer 4 | def removeDuplicates(self, A): 5 | if not A: 6 | return 0 7 | j = 0 8 | counter = 0 # How many times repeated (1 for twice) 9 | n = len(A) 10 | for i in range(1, n): 11 | if A[i] == A[j] and counter <= 0: 12 | j += 1 13 | A[j] = A[i] 14 | counter += 1 15 | elif A[i] != A[j]: 16 | j += 1 17 | A[j] = A[i] 18 | counter = 0 19 | return j + 1 20 | -------------------------------------------------------------------------------- /remove_duplicates_from_sorted_list/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a sorted linked list, delete all duplicates such that each element 3 | appear only once. 4 | 5 | For example, 6 | Given 1->1->2, return 1->2. 7 | Given 1->1->2->3->3, return 1->2->3. 8 | """ 9 | 10 | # Definition for singly-linked list. 11 | # class ListNode(object): 12 | # def __init__(self, x): 13 | # self.val = x 14 | # self.next = None 15 | 16 | class Solution(object): 17 | def deleteDuplicates(self, head): 18 | """ 19 | :type head: ListNode 20 | :rtype: ListNode 21 | """ 22 | if head is None: 23 | return None 24 | if head.next is None: 25 | return head 26 | last = head 27 | current = head.next 28 | while current is not None: 29 | next_node = current.next 30 | if current.val == last.val: 31 | last.next = next_node 32 | else: 33 | last = current 34 | current = next_node 35 | return head 36 | -------------------------------------------------------------------------------- /remove_duplicates_from_sorted_list_ii/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a sorted linked list, delete all nodes that have duplicate numbers, 3 | leaving only distinct numbers from the original list. 4 | 5 | For example, 6 | Given 1->2->3->3->4->4->5, return 1->2->5. 7 | Given 1->1->1->2->3, return 2->3. 8 | 9 | """ 10 | 11 | # Definition for singly-linked list. 12 | # class ListNode(object): 13 | # def __init__(self, x): 14 | # self.val = x 15 | # self.next = None 16 | 17 | class Solution(object): 18 | def deleteDuplicates(self, head): 19 | """ 20 | :type head: ListNode 21 | :rtype: ListNode 22 | """ 23 | d = {} 24 | current = head 25 | while current is not None: 26 | if current.val not in d: 27 | d[current.val] = 1 28 | else: 29 | d[current.val] += 1 30 | current = current.next 31 | current = head 32 | dummy = ListNode(0) 33 | dummy_end = dummy 34 | while current is not None: 35 | if d[current.val] == 1: 36 | dummy_end.next = current 37 | dummy_end = current 38 | current = current.next 39 | dummy_end.next = None 40 | return dummy.next 41 | -------------------------------------------------------------------------------- /remove_duplicates_from_sorted_list_ii/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a sorted linked list, delete all nodes that have duplicate numbers, 3 | leaving only distinct numbers from the original list. 4 | 5 | For example, 6 | Given 1->2->3->3->4->4->5, return 1->2->5. 7 | Given 1->1->1->2->3, return 2->3. 8 | 9 | """ 10 | 11 | # Definition for singly-linked list. 12 | # class ListNode(object): 13 | # def __init__(self, x): 14 | # self.val = x 15 | # self.next = None 16 | 17 | class Solution(object): 18 | def deleteDuplicates(self, head): 19 | """ 20 | :type head: ListNode 21 | :rtype: ListNode 22 | """ 23 | if head is None: 24 | return None 25 | current = head 26 | last = None 27 | count = 0 # Repeated count of `last` 28 | dummy = ListNode(0) 29 | dummy_end = dummy 30 | while current is not None: 31 | if last is not None: 32 | if current.val == last.val: 33 | count += 1 34 | else: 35 | if count == 0: 36 | dummy_end.next = last 37 | dummy_end = last 38 | count = 0 39 | last = current 40 | current = current.next 41 | if count == 0: 42 | dummy_end.next = last 43 | dummy_end = last 44 | dummy_end.next = None 45 | return dummy.next 46 | -------------------------------------------------------------------------------- /remove_element/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an array and a value, remove all instances of that value in place and 3 | return the new length. 4 | 5 | The order of elements can be changed. It doesn't matter what you leave beyond 6 | the new length. 7 | """ 8 | 9 | class Solution(object): 10 | def removeElement(self, nums, val): 11 | """ 12 | :type nums: List[int] 13 | :type val: int 14 | :rtype: int 15 | """ 16 | n = len(nums) 17 | j = 0 18 | for i in range(n): 19 | if nums[i] != val: 20 | nums[j] = nums[i] 21 | j += 1 22 | return j 23 | -------------------------------------------------------------------------------- /remove_linked_list_elements/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Remove all elements from a linked list of integers that have value val. 3 | 4 | Example 5 | Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6 6 | Return: 1 --> 2 --> 3 --> 4 --> 5 7 | """ 8 | 9 | # Definition for singly-linked list. 10 | # class ListNode(object): 11 | # def __init__(self, x): 12 | # self.val = x 13 | # self.next = None 14 | 15 | class Solution(object): 16 | def removeElements(self, head, val): 17 | """ 18 | :type head: ListNode 19 | :type val: int 20 | :rtype: ListNode 21 | """ 22 | if head is None: 23 | return None 24 | current = head 25 | last = None 26 | while current is not None: 27 | if current.val == val: 28 | if last is not None: 29 | # Remove `current` node and `last` node is not changed 30 | last.next = current.next 31 | else: 32 | # `current` is the head node 33 | # Remove the head node and `last` node is still None 34 | head = current.next 35 | last = None 36 | else: 37 | last = current 38 | current = current.next 39 | return head 40 | -------------------------------------------------------------------------------- /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 | # @return a ListNode 9 | def removeNthFromEnd(self, head, n): 10 | if head is None: 11 | return None 12 | elif n == 0: 13 | return head 14 | else: 15 | q = p = pp = head # `pp` is the node preceding `p` 16 | while q is not None: 17 | if n <= 0: 18 | pp = p 19 | p = p.next 20 | q = q.next 21 | n -= 1 22 | # Remove the head node 23 | if pp is p: 24 | head = pp.next 25 | else: 26 | pp.next = p.next 27 | # Free p 28 | return head 29 | -------------------------------------------------------------------------------- /remove_nth_node_from_end_of_list/solution2.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 | # @return a ListNode 9 | def removeNthFromEnd(self, head, n): 10 | if head is None: 11 | return head 12 | h = head 13 | p = None 14 | i = 0 15 | while head is not None: 16 | if i == n: 17 | p = h 18 | elif i > n: 19 | p = p.next 20 | i += 1 21 | head = head.next 22 | if p is None: 23 | return h.next 24 | else: 25 | p.next = p.next.next 26 | return h 27 | -------------------------------------------------------------------------------- /restore_ip_addresses/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a string containing only digits, restore it by returning all possible 3 | valid IP address combinations. 4 | 5 | For example: 6 | Given "25525511135", 7 | 8 | return ["255.255.11.135", "255.255.111.35"]. (Order does not matter) 9 | """ 10 | 11 | class Solution: 12 | # @param {string} s 13 | # @return {string[]} 14 | def restoreIpAddresses(self, s): 15 | res = [] 16 | cand = [] 17 | self.restore_ip(s, cand, res) 18 | return res 19 | 20 | def restore_ip(self, s, cand, res): 21 | # If more than 4 parts, or 4 parts already but with remaining 22 | # unprocessed sub-string 23 | if len(cand) > 4 or len(cand) == 4 and s: 24 | return 25 | elif not s and len(cand) == 4: 26 | res.append('.'.join(cand)) 27 | else: 28 | k = min(3, len(s)) # Ensures s[:j + 1] won't be duplicate 29 | for j in range(k): 30 | b = s[:j + 1] 31 | if self.is_valid_byte(b): 32 | cand.append(b) 33 | self.restore_ip(s[j + 1:], cand, res) 34 | cand.pop() 35 | 36 | def is_valid_byte(self, b): 37 | if b == '0': 38 | return True 39 | elif b.startswith('0'): 40 | return False 41 | else: 42 | return int(b) < 256 43 | 44 | a = "25525511135" 45 | b = "010010" 46 | s = Solution() 47 | print(s.restoreIpAddresses(a)) 48 | print(s.restoreIpAddresses(b)) 49 | -------------------------------------------------------------------------------- /reverse_bits/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param n, an integer 3 | # @return an integer 4 | def reverseBits(self, n): 5 | res = 0 6 | size = 32 7 | for i in range(size): 8 | if self.test_bit(n, i): 9 | print(i) 10 | res = self.set_bit(res, size - 1 - i) 11 | return res 12 | 13 | def test_bit(self, n, i): 14 | mask = 1 << i 15 | if n & mask > 0: 16 | return True 17 | return False 18 | 19 | def set_bit(self, n, i): 20 | mask = 1 << i 21 | return n | mask 22 | 23 | s = Solution() 24 | print(bin(43261596)) 25 | res = s.reverseBits(43261596) 26 | print(bin(res)) 27 | -------------------------------------------------------------------------------- /reverse_integer/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Reverse digits of an integer. 3 | 4 | Example1: x = 123, return 321 5 | Example2: x = -123, return -321 6 | """ 7 | 8 | class Solution(object): 9 | def reverse(self, x): 10 | """ 11 | :type x: int 12 | :rtype: int 13 | """ 14 | pos = True 15 | if x < 0: 16 | pos = False 17 | x = -x 18 | t = 0 19 | while x != 0: 20 | t = t * 10 + x % 10 21 | x /= 10 22 | if not pos: 23 | return -t 24 | return t 25 | -------------------------------------------------------------------------------- /reverse_linked_list/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Reverse a singly linked list. 3 | 4 | click to show more hints. 5 | 6 | Hint: 7 | A linked list can be reversed either iteratively or recursively. Could you 8 | implement both? 9 | """ 10 | 11 | # Definition for singly-linked list. 12 | class ListNode(object): 13 | def __init__(self, x): 14 | self.val = x 15 | self.next = None 16 | 17 | 18 | class Solution(object): 19 | def reverseList(self, head): 20 | """ 21 | :type head: ListNode 22 | :rtype: ListNode 23 | 24 | Iterative 25 | """ 26 | res = None 27 | while head is not None: 28 | next_node = head.next 29 | # First node encountered 30 | if res is None: 31 | res = head 32 | res.next = None 33 | else: 34 | # Insert to the head of `res` 35 | head.next = res 36 | res = head 37 | head = next_node 38 | return res 39 | 40 | 41 | n1 = ListNode(1) 42 | n2 = ListNode(2) 43 | n1.next = n2 44 | s = Solution() 45 | r1 = s.reverseList(n1) 46 | print r1.val 47 | print r1.next.val 48 | print r1.next.next.val 49 | -------------------------------------------------------------------------------- /reverse_linked_list/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Reverse a singly linked list. 3 | 4 | click to show more hints. 5 | 6 | Hint: 7 | A linked list can be reversed either iteratively or recursively. Could you 8 | implement both? 9 | """ 10 | 11 | # Definition for singly-linked list. 12 | class ListNode(object): 13 | def __init__(self, x): 14 | self.val = x 15 | self.next = None 16 | 17 | 18 | class Solution(object): 19 | def reverseList(self, head): 20 | """ 21 | :type head: ListNode 22 | :rtype: ListNode 23 | 24 | Recursive (Time Limit Exceeded) 25 | """ 26 | if head is None: 27 | return None 28 | else: 29 | rev_rest = self.reverseList(head.next) 30 | current = rev_rest 31 | if current is None: 32 | return head 33 | while current and current.next is not None: 34 | current = current.next 35 | current.next = head 36 | head.next = None 37 | return rev_rest 38 | 39 | 40 | n1 = ListNode(1) 41 | n2 = ListNode(2) 42 | n3 = ListNode(3) 43 | n1.next = n2 44 | n2.next = n3 45 | s = Solution() 46 | r1 = s.reverseList(n1) 47 | print r1.val 48 | print r1.next.val 49 | print r1.next.next.val 50 | -------------------------------------------------------------------------------- /reverse_linked_list_ii/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 | # @param head, a ListNode 9 | # @param m, an integer 10 | # @param n, an integer 11 | # @return a ListNode 12 | def reverseBetween(self, head, m, n): 13 | i = 1 14 | res = head # Start of the beginning part 15 | res_end = head # End of the beginning part 16 | rev = None # Start of reversed part 17 | rev_end = None # End of reversed part 18 | while head is not None: 19 | next_node = head.next 20 | if i < m: 21 | res_end = head 22 | elif i >= m and i <= n: 23 | head.next = rev 24 | rev = head 25 | if i == m: 26 | rev_end = head 27 | else: # i > n 28 | break 29 | head = next_node 30 | i += 1 31 | # No beginning part 32 | if m == 1: 33 | res = rev 34 | res_end = rev_end 35 | else: 36 | res_end.next = rev 37 | rev_end.next = head 38 | return res 39 | -------------------------------------------------------------------------------- /roman_to_integer/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a roman numeral, convert it to an integer. 3 | 4 | Input is guaranteed to be within the range from 1 to 3999. 5 | """ 6 | 7 | 8 | class Solution(object): 9 | def romanToInt(self, s): 10 | """ 11 | :type s: str 12 | :rtype: int 13 | """ 14 | roman = { 15 | 'I': 1, 16 | 'V': 5, 17 | 'X': 10, 18 | 'L': 50, 19 | 'C': 100, 20 | 'D': 500, 21 | 'M': 1000, 22 | } 23 | res = 0 24 | for i, c in enumerate(s): 25 | if i < len(s) - 1 and roman[c] < roman[s[i + 1]]: 26 | res -= roman[c] 27 | else: 28 | res += roman[c] 29 | return res 30 | -------------------------------------------------------------------------------- /rotate_array/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Rotate an array of n elements to the right by k steps. 3 | 4 | For example, with n = 7 and k = 3, the array [1,2,3,4,5,6,7] is rotated to 5 | [5,6,7,1,2,3,4]. 6 | 7 | Note: 8 | Try to come up as many solutions as you can, there are at least 3 different 9 | ways to solve this problem. 10 | """ 11 | 12 | class Solution(object): 13 | def rotate(self, nums, k): 14 | """ 15 | :type nums: List[int] 16 | :type k: int 17 | :rtype: void Do not return anything, modify nums in-place instead. 18 | """ 19 | n = len(nums) 20 | k = k % n 21 | self.reverse(nums, 0, n - 1) 22 | self.reverse(nums, 0, k - 1) 23 | self.reverse(nums, k, n - 1) 24 | 25 | def reverse(self, nums, i, j): 26 | while i < j: 27 | nums[i], nums[j] = nums[j], nums[i] 28 | i += 1 29 | j -= 1 30 | 31 | 32 | a1 = [1, 2, 3, 4, 5, 6, 7] 33 | s = Solution() 34 | s.rotate(a1, 3) 35 | print(a1) 36 | 37 | a2 = [1] 38 | s.rotate(a2, 2) 39 | print(a2) 40 | -------------------------------------------------------------------------------- /rotate_image/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param matrix, a list of lists of integers 3 | # @return a list of lists of integers 4 | def rotate(self, matrix): 5 | n = len(matrix) 6 | # Layers 7 | for i in range(n / 2): 8 | # Each layer's index range 9 | start = i 10 | end = n - 1 - i 11 | for j in range(start, end): 12 | offset = j - start 13 | top = matrix[start][j] 14 | # Left to Top 15 | matrix[start][j] = matrix[end - offset][start] 16 | # Bottom to Left 17 | matrix[end - offset][start] = matrix[end][end - offset] 18 | # Right to Bottom 19 | matrix[end][end - offset] = matrix[j][end] 20 | # Top to Right 21 | matrix[j][end] = top 22 | return matrix 23 | -------------------------------------------------------------------------------- /rotate_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 | # @param head, a ListNode 9 | # @param k, an integer 10 | # @return a ListNode 11 | def rotateRight(self, head, k): 12 | if head is None: 13 | return None 14 | n = 0 15 | h = head 16 | while head is not None: 17 | n += 1 18 | head = head.next 19 | k = k % n 20 | if k == 0: 21 | return h 22 | res = h # Head of result 23 | prev = h # Previous node of result 24 | i = 0 25 | while res is not None: 26 | if i == n - k: 27 | break 28 | prev = res 29 | res = res.next 30 | i += 1 31 | end = res 32 | while end.next is not None: 33 | end = end.next 34 | end.next = h 35 | prev.next = None 36 | return res 37 | -------------------------------------------------------------------------------- /same_tree/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given two binary trees, write a function to check if they are equal or not. 3 | 4 | Two binary trees are considered equal if they are structurally identical and 5 | the nodes have the same value. 6 | """ 7 | 8 | # Definition for a binary tree node. 9 | # class TreeNode(object): 10 | # def __init__(self, x): 11 | # self.val = x 12 | # self.left = None 13 | # self.right = None 14 | 15 | class Solution(object): 16 | def isSameTree(self, p, q): 17 | """ 18 | :type p: TreeNode 19 | :type q: TreeNode 20 | :rtype: bool 21 | """ 22 | if p is None and q is None: 23 | return True 24 | elif p is not None and q is not None: 25 | if (p.val == q.val and 26 | self.isSameTree(p.left, q.left) and 27 | self.isSameTree(p.right, q.right)): 28 | return True 29 | return False 30 | -------------------------------------------------------------------------------- /search_in_rotated_sorted_array/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Suppose a sorted array is rotated at some pivot unknown to you beforehand. 3 | 4 | (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). 5 | 6 | You are given a target value to search. If found in the array return its 7 | index, otherwise return -1. 8 | 9 | You may assume no duplicate exists in the array. 10 | """ 11 | 12 | class Solution(object): 13 | def search(self, nums, target): 14 | """ 15 | :type nums: List[int] 16 | :type target: int 17 | :rtype: int 18 | """ 19 | left = 0 20 | right = len(nums) - 1 21 | while left <= right: 22 | mid = left + (right - left) / 2 23 | if target == nums[mid]: 24 | return mid 25 | # Left part is sorted 26 | elif nums[mid] > nums[right]: 27 | if target < nums[mid] and target >= nums[left]: 28 | right = mid - 1 29 | else: 30 | left = mid + 1 31 | # Right part is sorted 32 | else: 33 | if target > nums[mid] and target <= nums[right]: 34 | left = mid + 1 35 | else: 36 | right = mid - 1 37 | return -1 38 | -------------------------------------------------------------------------------- /search_in_rotated_sorted_array/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Suppose a sorted array is rotated at some pivot unknown to you beforehand. 3 | 4 | (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). 5 | 6 | You are given a target value to search. If found in the array return its 7 | index, otherwise return -1. 8 | 9 | You may assume no duplicate exists in the array. 10 | """ 11 | 12 | class Solution(object): 13 | def search(self, nums, target): 14 | """ 15 | :type nums: List[int] 16 | :type target: int 17 | :rtype: int 18 | """ 19 | left = 0 20 | right = len(nums) - 1 21 | while left + 1 < right: 22 | mid = left + (right - left) / 2 23 | if target == nums[mid]: 24 | return mid 25 | # Right side is sorted 26 | elif nums[mid] < nums[right]: 27 | if nums[mid] <= target <= nums[right]: 28 | left = mid 29 | else: 30 | right = mid 31 | # Left side is sorted 32 | else: 33 | if nums[left] <= target <= nums[mid]: 34 | right = mid 35 | else: 36 | left = mid 37 | if nums[left] == target: 38 | return left 39 | elif nums[right] == target: 40 | return right 41 | return -1 42 | -------------------------------------------------------------------------------- /search_in_rotated_sorted_array_ii/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Suppose a sorted array is rotated at some pivot unknown to you beforehand. 3 | 4 | (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). 5 | 6 | Follow up for "Search in Rotated Sorted Array": 7 | 8 | What if duplicates are allowed? 9 | 10 | Would this affect the run-time complexity? How and why? 11 | 12 | Write a function to determine if a given target is in the array. 13 | """ 14 | 15 | class Solution(object): 16 | def search(self, nums, target): 17 | """ 18 | :type nums: List[int] 19 | :type target: int 20 | :rtype: bool 21 | """ 22 | left = 0 23 | right = len(nums) - 1 24 | while left <= right: 25 | mid = left + (right - left) / 2 26 | if target == nums[mid]: 27 | return True 28 | # Left part is sorted 29 | elif nums[mid] > nums[right]: 30 | if target < nums[mid] and target >= nums[left]: 31 | right = mid - 1 32 | else: 33 | left = mid + 1 34 | # Right part is sorted 35 | elif nums[mid] < nums[right]: 36 | if target > nums[mid] and target <= nums[right]: 37 | left = mid + 1 38 | else: 39 | right = mid - 1 40 | else: 41 | right -= 1 42 | return False 43 | -------------------------------------------------------------------------------- /search_in_rotated_sorted_array_ii/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Suppose a sorted array is rotated at some pivot unknown to you beforehand. 3 | 4 | (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). 5 | 6 | Follow up for "Search in Rotated Sorted Array": 7 | 8 | What if duplicates are allowed? 9 | 10 | Would this affect the run-time complexity? How and why? 11 | 12 | Write a function to determine if a given target is in the array. 13 | """ 14 | 15 | class Solution(object): 16 | def search(self, nums, target): 17 | """ 18 | :type nums: List[int] 19 | :type target: int 20 | :rtype: bool 21 | """ 22 | left = 0 23 | right = len(nums) - 1 24 | while left + 1 < right: 25 | mid = left + (right - left) / 2 26 | if target == nums[mid]: 27 | return True 28 | # Left part is sorted 29 | elif nums[mid] > nums[right]: 30 | if nums[left] <= target < nums[mid]: 31 | right = mid 32 | else: 33 | left = mid 34 | # Right part is sorted 35 | elif nums[mid] < nums[right]: 36 | if nums[mid] < target <= nums[right]: 37 | left = mid 38 | else: 39 | right = mid 40 | else: 41 | right -= 1 42 | if nums[left] == target or nums[right] == target: 43 | return True 44 | return False 45 | -------------------------------------------------------------------------------- /search_insert_position/solution.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Given a sorted array and a target value, return the index if the target is 4 | found. If not, return the index where it would be if it were inserted in 5 | order. 6 | 7 | You may assume no duplicates in the array. 8 | 9 | Here are few examples. 10 | [1,3,5,6], 5 → 2 11 | [1,3,5,6], 2 → 1 12 | [1,3,5,6], 7 → 4 13 | [1,3,5,6], 0 → 0 14 | 15 | """ 16 | 17 | class Solution(object): 18 | def searchInsert(self, nums, target): 19 | """ 20 | :type nums: List[int] 21 | :type target: int 22 | :rtype: int 23 | """ 24 | n = len(nums) 25 | if not nums: 26 | return 0 27 | else: 28 | left = 0 29 | right = n - 1 30 | while left <= right: 31 | mid = (left + right) / 2 32 | if nums[mid] == target: 33 | return mid 34 | elif (mid < n - 1 and nums[mid] < target 35 | and nums[mid + 1] > target): 36 | return mid + 1 37 | elif target < nums[mid]: 38 | right = mid - 1 39 | else: 40 | left = mid + 1 41 | if left > n - 1: 42 | return n 43 | elif right < 0: 44 | return 0 45 | 46 | 47 | a = [1, 3, 5, 6] 48 | s = Solution() 49 | print(s.searchInsert(a, 5)) 50 | print(s.searchInsert(a, 2)) 51 | print(s.searchInsert(a, 7)) 52 | print(s.searchInsert(a, 0)) 53 | -------------------------------------------------------------------------------- /search_insert_position/solution2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Given a sorted array and a target value, return the index if the target is 4 | found. If not, return the index where it would be if it were inserted in 5 | order. 6 | 7 | You may assume no duplicates in the array. 8 | 9 | Here are few examples. 10 | [1,3,5,6], 5 → 2 11 | [1,3,5,6], 2 → 1 12 | [1,3,5,6], 7 → 4 13 | [1,3,5,6], 0 → 0 14 | 15 | """ 16 | 17 | class Solution(object): 18 | def searchInsert(self, nums, target): 19 | n = len(nums) 20 | left = 0 21 | right = n - 1 22 | while left + 1 < right: 23 | mid = left + (right - left) / 2 24 | if mid > 0 and nums[mid - 1] < target < nums[mid]: 25 | return mid 26 | elif target <= nums[mid]: 27 | right = mid 28 | else: 29 | left = mid 30 | if nums[left] < target < nums[right]: 31 | return left + 1 32 | elif nums[left] == target: 33 | return left 34 | elif nums[right] == target: 35 | return right 36 | elif nums[left] > target: 37 | return min(0, left) 38 | elif nums[right] < target: 39 | return max(n, right) 40 | 41 | 42 | a1 = [1, 3] 43 | s = Solution() 44 | print s.searchInsert(a1, 2) 45 | -------------------------------------------------------------------------------- /set_matrix_zeroes/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param matrix, a list of lists of integers 3 | # RETURN NOTHING, MODIFY matrix IN PLACE. 4 | def setZeroes(self, matrix): 5 | n = len(matrix) 6 | m = len(matrix[0]) 7 | column_zero = False 8 | row_zero = False 9 | for i in range(n): 10 | for j in range(m): 11 | if matrix[i][j] == 0: 12 | # Check whether the first row and column contain 13 | # zeroes before recording 14 | if i == 0: 15 | row_zero = True 16 | if j == 0: 17 | column_zero = True 18 | # Record zeroes using the first row and column 19 | matrix[i][0] = 0 20 | matrix[0][j] = 0 21 | # Set zeroes except for the first row and column 22 | for i in range(n): 23 | for j in range(m): 24 | if i > 0 and j > 0: 25 | if matrix[0][j] == 0 or matrix[i][0] == 0: 26 | matrix[i][j] = 0 27 | # Set the first row and column 28 | if row_zero: 29 | for j in range(m): 30 | matrix[0][j] = 0 31 | if column_zero: 32 | for i in range(n): 33 | matrix[i][0] = 0 34 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [flake8] 2 | ignore = E302 3 | -------------------------------------------------------------------------------- /simplify_path/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param path, a string 3 | # @return a string 4 | def simplifyPath(self, path): 5 | ps = path.split('/')[1:] 6 | res = [] 7 | for d in ps: 8 | if d == '..': 9 | if res: 10 | res.pop() 11 | elif d == '.' or d == '': 12 | pass 13 | else: 14 | res.append(d) 15 | return '/' + '/'.join(res) 16 | -------------------------------------------------------------------------------- /single_number/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param A, a list of integer 3 | # @return an integer 4 | def singleNumber(self, A): 5 | if not A: 6 | return None 7 | p = A[0] 8 | for i in range(1, len(A)): 9 | p = p ^ A[i] 10 | return p 11 | -------------------------------------------------------------------------------- /single_number_ii/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param A, a list of integer 3 | # @return an integer 4 | def singleNumber(self, A): 5 | # Assume 32-bit integer 6 | num_of_bits = 32 # Change this to 64 on 64-bit platform 7 | res_bit = 0 8 | res = 0 9 | # First check whether the single number is negative 10 | for num in A: 11 | bit = 1 if num & (1 << (num_of_bits - 1)) != 0 else 0 12 | res_bit = (res_bit + bit) % 3 13 | positive = True if res_bit == 0 else False 14 | 15 | for i in range(num_of_bits - 1): 16 | res_bit = 0 17 | # For each bit of each number, calculate each bit 18 | # of the single number 19 | for num in A: 20 | bit = 1 if num & (1 << i) != 0 else 0 21 | res_bit = (res_bit + bit) % 3 22 | # If single number is positive 23 | if positive and res_bit == 1: 24 | res += 1 << i 25 | # If single number is negative 26 | if not positive and res_bit == 0: 27 | res += 1 << i 28 | if not positive: 29 | res = -(res + 1) 30 | return res 31 | -------------------------------------------------------------------------------- /single_number_ii/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given an array of integers, every element appears three times except for one. 3 | Find that single one. 4 | 5 | Note: 6 | Your algorithm should have a linear runtime complexity. Could you implement it 7 | without using extra memory? 8 | """ 9 | 10 | 11 | class Solution(object): 12 | def singleNumber(self, nums): 13 | """ 14 | :type nums: List[int] 15 | :rtype: int 16 | 17 | Not correct on LeetCode 18 | """ 19 | # An 32-bit integer has at most 20 bits as base-3 20 | m = 20 21 | pow3 = [1 for _ in range(m)] 22 | for i in range(1, m): 23 | pow3[i] = pow3[i - 1] * 3 24 | print pow3 25 | 26 | bits = [0 for _ in range(m)] 27 | # For each bit of every integer, do XOR on three elements 28 | for i in range(m): 29 | for c in nums: 30 | bits[i] = (bits[i] + c / pow3[i]) % 3 31 | res = 0 32 | for i in range(m): 33 | res += pow3[i] * bits[i] 34 | return res 35 | 36 | 37 | a1 = [2, 2, 3, 2] 38 | s = Solution() 39 | print s.singleNumber(a1) 40 | -------------------------------------------------------------------------------- /sort_colors/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param A a list of integers 3 | # @return nothing, sort in place 4 | def sortColors(self, A): 5 | n = len(A) 6 | r = 0 # Last index of red 7 | b = n - 1 # First index of white 8 | i = 0 9 | while i <= b: 10 | if A[i] == 0: 11 | A[i], A[r] = A[r], A[i] 12 | r += 1 13 | # Increment i because swapped item must be 1 or 0 14 | i += 1 15 | elif A[i] == 2: 16 | A[i], A[b] = A[b], A[i] 17 | b -= 1 18 | # Do not increment i, since swapped item may be 0, 1, or 2 19 | continue 20 | # A[i] == 1 21 | else: 22 | i += 1 23 | -------------------------------------------------------------------------------- /spiral_matrix_ii/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @return a list of lists of integer 3 | def generateMatrix(self, n): 4 | matrix = [[0 for i in range(n)] for j in range(n)] 5 | count = 1 6 | for i in range(n / 2): 7 | start = i 8 | end = n - i - 1 9 | width = end - start 10 | for j in range(start, end): 11 | offset = j - start 12 | # Top 13 | matrix[start][j] = count + offset 14 | # Right 15 | matrix[j][end] = count + width + offset 16 | # Bottom 17 | matrix[end][end - offset] = count + 2 * width + offset 18 | # Left 19 | matrix[end - offset][start] = count + 3 * width + offset 20 | count += 4 * width 21 | if n % 2 == 1: 22 | mid = n / 2 23 | matrix[mid][mid] = count 24 | return matrix 25 | -------------------------------------------------------------------------------- /sqrt(x)/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param x, an integer 3 | # @return an integer 4 | def sqrt(self, x): 5 | left = 0 6 | right = x 7 | while left <= right: 8 | mid = left + (right - left) / 2 9 | square = mid * mid 10 | if square == x: 11 | return mid 12 | elif square < x: 13 | left = mid + 1 14 | else: 15 | right = mid - 1 16 | return (left + right) / 2 17 | -------------------------------------------------------------------------------- /subsets/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param S, a list of integer 3 | # @return a list of lists of integer 4 | def subsets(self, S): 5 | S.sort() 6 | return self._subsets(S, len(S)) 7 | 8 | def _subsets(self, S, k): 9 | if k == 0: 10 | return [[]] 11 | else: 12 | res = [[]] 13 | for i in range(len(S)): 14 | rest_subsets = self._subsets(S[i + 1:], k - 1) 15 | for subset in rest_subsets: 16 | subset.insert(0, S[i]) 17 | res += rest_subsets 18 | return res 19 | -------------------------------------------------------------------------------- /subsets/solution2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param S, a list of integer 3 | # @return a list of lists of integer 4 | def subsets(self, S): 5 | S.sort() 6 | return self.subsets_aux(S) 7 | 8 | def subsets_aux(self, S): 9 | if not S: 10 | return [[]] 11 | else: 12 | res = [[]] 13 | for i, e in enumerate(S): 14 | rest_subsets = self.subsets_aux(S[i + 1:]) 15 | for subset in rest_subsets: 16 | subset.insert(0, e) 17 | res += rest_subsets 18 | return res 19 | -------------------------------------------------------------------------------- /subsets/solution3.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param S, a list of integer 3 | # @return a list of lists of integer 4 | def subsets(self, S): 5 | S.sort() 6 | cand = [] 7 | res = [] 8 | self.subsets_aux(S, cand, res) 9 | return res 10 | 11 | def subsets_aux(self, S, cand, res): 12 | res.append(cand[:]) 13 | for i, e in enumerate(S): 14 | cand.append(S[i]) 15 | self.subsets_aux(S[i + 1:], cand, res) 16 | cand.pop() 17 | 18 | s = Solution() 19 | print(s.subsets([1, 2, 3])) 20 | -------------------------------------------------------------------------------- /subsets/solution4.py: -------------------------------------------------------------------------------- 1 | # Using bit manipulation 2 | class Solution: 3 | # @param S, a list of integer 4 | # @return a list of lists of integer 5 | def subsets(self, S): 6 | S.sort() 7 | k = len(S) 8 | n = 2 ** k 9 | res = [] 10 | for i in range(n): 11 | s = self.filter(S, k, i) 12 | res.append(s) 13 | return res 14 | 15 | def filter(self, S, k, i): 16 | res = [] 17 | for j in range(k): 18 | mask = 1 << j 19 | if i & mask > 0: 20 | res.append(S[j]) 21 | return res 22 | 23 | s = Solution() 24 | print(s.subsets([1, 2, 3])) 25 | -------------------------------------------------------------------------------- /subsets_ii/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param num, a list of integer 3 | # @return a list of lists of integer 4 | def subsetsWithDup(self, S): 5 | S.sort() 6 | return self._subsets(S, len(S)) 7 | 8 | def _subsets(self, S, k): 9 | if k == 0: 10 | return [[]] 11 | else: 12 | res = [[]] 13 | for i in range(len(S)): 14 | if i > 0 and S[i] == S[i - 1]: 15 | pass 16 | else: 17 | rest_subsets = self._subsets(S[i + 1:], k - 1) 18 | for subset in rest_subsets: 19 | subset.insert(0, S[i]) 20 | res += rest_subsets 21 | return res 22 | -------------------------------------------------------------------------------- /subsets_ii/solution2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param {integer[]} nums 3 | # @return {integer[][]} 4 | def subsetsWithDup(self, nums): 5 | nums.sort() 6 | return self.subsets_aux(nums) 7 | 8 | def subsets_aux(self, nums): 9 | if not nums: 10 | return [[]] 11 | else: 12 | res = [[]] 13 | for i, e in enumerate(nums): 14 | if i > 0 and nums[i] == nums[i - 1]: 15 | continue 16 | rest_subsets = self.subsets_aux(nums[i + 1:]) 17 | for subset in rest_subsets: 18 | subset.insert(0, e) 19 | res += rest_subsets 20 | return res 21 | 22 | s = Solution() 23 | print s.subsetsWithDup([1, 2, 2]) 24 | -------------------------------------------------------------------------------- /sum_root_to_leaf_numbers/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 | class Solution: 9 | # @param root, a tree node 10 | # @return an integer 11 | def sumNumbers(self, root): 12 | self.res = 0 # global variable for sum 13 | num = 0 14 | self.sn(root, num) 15 | return self.res 16 | 17 | def sn(self, root, num): 18 | if root is None: 19 | return 20 | elif root.left is None and root.right is None: 21 | num += root.val 22 | self.res += num 23 | else: 24 | num += root.val 25 | self.sn(root.left, 10 * num) 26 | self.sn(root.right, 10 * num) 27 | -------------------------------------------------------------------------------- /summary_ranges/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a sorted integer array without duplicates, return the summary of its 3 | ranges. 4 | 5 | For example, given [0,1,2,4,5,7], return ["0->2","4->5","7"]. 6 | """ 7 | 8 | class Solution(object): 9 | def summaryRanges(self, nums): 10 | """ 11 | :type nums: List[int] 12 | :rtype: List[str] 13 | """ 14 | res = [] 15 | n = len(nums) 16 | start = -1 17 | end = -1 18 | for i, e in enumerate(nums): 19 | if i == 0: 20 | start = 0 21 | end = 0 22 | else: 23 | if e != nums[i - 1] + 1: 24 | r = self.make_range(start, end, nums) 25 | res.append(r) 26 | start = i 27 | end = i 28 | if i == n - 1: 29 | end = i 30 | r = self.make_range(start, end, nums) 31 | res.append(r) 32 | return res 33 | 34 | def make_range(self, start, end, nums): 35 | if end > start: 36 | return "%d->%d" % (nums[start], nums[end]) 37 | elif end == start: 38 | return "%d" % nums[end] 39 | 40 | 41 | a1 = [0, 1, 2, 4, 5, 7] 42 | a2 = [0, 5, 9] 43 | s = Solution() 44 | print(s.summaryRanges(a1)) 45 | print(s.summaryRanges(a2)) 46 | -------------------------------------------------------------------------------- /swap_nodes_in_pairs/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 | # @param a ListNode 9 | # @return a ListNode 10 | def swapPairs(self, head): 11 | if head is None or head.next is None: 12 | return head 13 | else: 14 | t = head.next 15 | head.next = self.swapPairs(t.next) 16 | t.next = head 17 | return t 18 | -------------------------------------------------------------------------------- /swap_nodes_in_pairs/solution2.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 | # @param a ListNode 9 | # @return a ListNode 10 | def swapPairs(self, head): 11 | if head is None: 12 | return head 13 | res = None 14 | res_end = None 15 | temp = None 16 | temp_end = None 17 | i = 1 18 | while head is not None: 19 | next_node = head.next 20 | # Append current node to temp list 21 | if temp is None: 22 | temp_end = head 23 | head.next = temp 24 | temp = head 25 | if i % 2 == 0: 26 | # Append temp to res 27 | if res is None: 28 | res = temp 29 | res_end = temp_end 30 | else: 31 | res_end.next = temp 32 | res_end = temp_end 33 | temp = None 34 | i += 1 35 | head = next_node 36 | if temp is not None: 37 | if res is None: 38 | res = temp 39 | res_end = temp_end 40 | else: 41 | res_end.next = temp 42 | res_end = temp_end 43 | return res 44 | -------------------------------------------------------------------------------- /symmetric_tree/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a binary tree, check whether it is a mirror of itself (ie, symmetric 3 | around its center). 4 | 5 | For example, this binary tree is symmetric: 6 | 7 | 1 8 | / \ 9 | 2 2 10 | / \ / \ 11 | 3 4 4 3 12 | But the following is not: 13 | 1 14 | / \ 15 | 2 2 16 | \ \ 17 | 3 3 18 | """ 19 | 20 | # Definition for a binary tree node. 21 | # class TreeNode(object): 22 | # def __init__(self, x): 23 | # self.val = x 24 | # self.left = None 25 | # self.right = None 26 | 27 | class Solution(object): 28 | def isSymmetric(self, root): 29 | """ 30 | :type root: TreeNode 31 | :rtype: bool 32 | """ 33 | if root is None: 34 | return True 35 | if root.left is None and root.right is None: 36 | return True 37 | if root.left is not None and root.right is not None: 38 | return self._isSymmetric(root.left, root.right) 39 | return False 40 | 41 | def _isSymmetric(self, left, right): 42 | if left is None and right is None: 43 | return True 44 | if left is not None and right is not None: 45 | return (left.val == right.val and 46 | self._isSymmetric(left.left, right.right) and 47 | self._isSymmetric(left.right, right.left)) 48 | return False 49 | -------------------------------------------------------------------------------- /trapping_rain_water/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param A, a list of integers 3 | # @return an integer 4 | def trap(self, A): 5 | n = len(A) 6 | res = 0 7 | last = 0 8 | stack = [] 9 | for i in range(1, n): 10 | if A[i] >= A[last]: 11 | # Calculate trapped water 12 | w = i - last - 1 13 | area = w * A[last] 14 | while stack: 15 | area -= A[stack.pop()] 16 | res += area 17 | last = i 18 | else: 19 | stack.append(i) 20 | # Process remaining bars 21 | if stack: 22 | r = stack.pop() # Rightmost effective bar 23 | while stack: 24 | if A[stack[-1]] >= A[r]: 25 | r = stack.pop() 26 | else: 27 | break 28 | while stack: 29 | i = stack.pop() 30 | if A[i] < A[r]: 31 | res += A[r] - A[i] 32 | else: 33 | r = i 34 | return res 35 | -------------------------------------------------------------------------------- /trapping_rain_water/solution2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param A, a list of integers 3 | # @return an integer 4 | def trap(self, A): 5 | n = len(A) 6 | num_max_left = [0 for i in range(n)] 7 | num_max_right = [0 for i in range(n)] 8 | max_left = 0 9 | max_right = 0 10 | res = 0 11 | for i in range(n): 12 | num_max_left[i] = max_left 13 | max_left = max(A[i], max_left) 14 | for i in range(n): 15 | j = n - 1 - i 16 | num_max_right[j] = max_right 17 | max_right = max(A[j], max_right) 18 | for i in range(1, n - 1): 19 | min_num = min(num_max_left[i], num_max_right[i]) 20 | if min_num > A[i]: 21 | res += min_num - A[i] 22 | return res 23 | -------------------------------------------------------------------------------- /triangle/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a triangle, find the minimum path sum from top to bottom. Each step you 3 | may move to adjacent numbers on the row below. 4 | 5 | For example, given the following triangle 6 | [ 7 | [2], 8 | [3,4], 9 | [6,5,7], 10 | [4,1,8,3] 11 | ] 12 | The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11). 13 | 14 | Note: 15 | Bonus point if you are able to do this using only O(n) extra space, where n is 16 | the total number of rows in the triangle. 17 | """ 18 | 19 | class Solution: 20 | # @param triangle, a list of lists of integers 21 | # @return an integer 22 | def minimumTotal(self, triangle): 23 | t = [[0 for col in row] for row in triangle] # Initialize t 24 | n = len(triangle) 25 | row = n - 1 26 | while row >= 0: 27 | if row == n - 1: 28 | for col in range(row + 1): 29 | t[row][col] = triangle[row][col] 30 | else: 31 | for col in range(row + 1): 32 | minsum = min(t[row + 1][col], t[row + 1][col + 1]) 33 | t[row][col] = triangle[row][col] + minsum 34 | row -= 1 35 | return t[0][0] 36 | -------------------------------------------------------------------------------- /two_sum/solution.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @return a tuple, (index1, index2) 3 | def twoSum(self, num, target): 4 | d = {} 5 | for i, e in enumerate(num): 6 | if e in d: 7 | return d[e] + 1, i + 1 8 | d[target - e] = i 9 | -------------------------------------------------------------------------------- /ugly_number/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Write a program to check whether a given number is an ugly number. 3 | 4 | Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. 5 | For example, 6, 8 are ugly while 14 is not ugly since it includes another 6 | prime factor 7. 7 | 8 | Note that 1 is typically treated as an ugly number. 9 | """ 10 | 11 | class Solution(object): 12 | def isUgly(self, num): 13 | """ 14 | :type num: int 15 | :rtype: bool 16 | """ 17 | if num == 0: 18 | return False 19 | factors = [2, 3, 5] 20 | for factor in factors: 21 | while num % factor == 0: 22 | num /= factor 23 | if num == 1: 24 | return True 25 | return False 26 | 27 | 28 | s = Solution() 29 | print s.isUgly(10) 30 | print s.isUgly(6) 31 | print s.isUgly(14) 32 | -------------------------------------------------------------------------------- /unique_binary_search_trees/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given n, how many structurally unique BST's (binary search trees) that store 3 | values 1...n? 4 | 5 | For example, 6 | Given n = 3, there are a total of 5 unique BST's. 7 | 8 | 1 3 3 2 1 9 | \ / / / \ \ 10 | 3 2 1 1 3 2 11 | / / \ \ 12 | 2 1 2 3 13 | """ 14 | 15 | class Solution(object): 16 | def numTrees(self, n): 17 | """ 18 | :type n: int 19 | :rtype: int 20 | """ 21 | t = [-1 for _ in range(n + 1)] 22 | return self.num_trees_aux(n, t) 23 | 24 | def num_trees_aux(self, n, t): 25 | if n == 0 or n == 1: 26 | return 1 27 | elif t[n] != -1: 28 | return t[n] 29 | else: 30 | res = 0 31 | for i in range(n): 32 | res += self.num_trees_aux(i, t) * \ 33 | self.num_trees_aux(n - 1 - i, t) 34 | t[n] = res 35 | return res 36 | -------------------------------------------------------------------------------- /unique_binary_search_trees/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given n, how many structurally unique BST's (binary search trees) that store 3 | values 1...n? 4 | 5 | For example, 6 | Given n = 3, there are a total of 5 unique BST's. 7 | 8 | 1 3 3 2 1 9 | \ / / / \ \ 10 | 3 2 1 1 3 2 11 | / / \ \ 12 | 2 1 2 3 13 | """ 14 | 15 | class Solution(object): 16 | def numTrees(self, n): 17 | t = [-1 for _ in range(n + 1)] 18 | t[0] = 1 19 | t[1] = 1 20 | if n <= 1: 21 | return t[n] 22 | else: 23 | for i in range(2, n + 1): 24 | res = 0 25 | for j in range(i): 26 | res += t[j] * t[i - 1 - j] 27 | t[i] = res 28 | return t[n] 29 | -------------------------------------------------------------------------------- /unique_binary_search_trees_ii/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 | class Solution: 9 | # @return a list of tree node 10 | def generateTrees(self, n): 11 | a = range(1, n + 1) 12 | return self.generate_bst(a) 13 | 14 | def generate_bst(self, a): 15 | if not a: 16 | return [None] 17 | else: 18 | res = [] 19 | for i, c in enumerate(a): 20 | left = self.generate_bst(a[:i]) 21 | right = self.generate_bst(a[i + 1:]) 22 | for l in left: 23 | for r in right: 24 | root = TreeNode(c) 25 | root.left = l 26 | root.right = r 27 | res.append(root) 28 | return res 29 | -------------------------------------------------------------------------------- /unique_paths/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | A robot is located at the top-left corner of a m x n grid (marked 'Start' in 3 | the diagram below). 4 | 5 | The robot can only move either down or right at any point in time. The robot 6 | is trying to reach the bottom-right corner of the grid (marked 'Finish' in the 7 | diagram below). 8 | 9 | How many possible unique paths are there? 10 | """ 11 | 12 | class Solution: 13 | # @return an integer 14 | def uniquePaths(self, m, n): 15 | t = [[1] * m] * n 16 | i = j = 0 17 | for i in range(n): 18 | for j in range(m): 19 | if i == 0 and j == 0: 20 | continue 21 | elif i == 0: 22 | t[i][j] = 1 23 | elif j == 0: 24 | t[i][j] = 1 25 | else: 26 | t[i][j] = t[i - 1][j] + t[i][j - 1] 27 | return t[n - 1][m - 1] 28 | -------------------------------------------------------------------------------- /unique_paths_ii/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Follow up for "Unique Paths": 3 | 4 | Now consider if some obstacles are added to the grids. How many unique paths 5 | would there be? 6 | 7 | An obstacle and empty space is marked as 1 and 0 respectively in the grid. 8 | 9 | For example, 10 | There is one obstacle in the middle of a 3x3 grid as illustrated below. 11 | 12 | [ 13 | [0,0,0], 14 | [0,1,0], 15 | [0,0,0] 16 | ] 17 | The total number of unique paths is 2. 18 | 19 | Note: m and n will be at most 100. 20 | """ 21 | 22 | class Solution: 23 | # @param obstacleGrid, a list of lists of integers 24 | # @return an integer 25 | def uniquePathsWithObstacles(self, obstacleGrid): 26 | grid = obstacleGrid 27 | n = len(grid) 28 | m = len(grid[0]) 29 | t = [[-1 for i in range(m)] for j in range(n)] 30 | for i in range(n): 31 | for j in range(m): 32 | if grid[i][j] == 1: 33 | t[i][j] = 0 34 | else: 35 | if i == 0 and j == 0: 36 | t[i][j] = 1 37 | elif i == 0: 38 | t[i][j] = t[i][j - 1] 39 | elif j == 0: 40 | t[i][j] = t[i - 1][j] 41 | else: 42 | t[i][j] = t[i - 1][j] + t[i][j - 1] 43 | return t[n - 1][m - 1] 44 | -------------------------------------------------------------------------------- /valid_anagram/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given two strings s and t, write a function to determine if t is an anagram of 3 | s. 4 | 5 | For example, 6 | s = "anagram", t = "nagaram", return true. 7 | s = "rat", t = "car", return false. 8 | 9 | Note: 10 | You may assume the string contains only lowercase alphabets. 11 | """ 12 | 13 | 14 | class Solution(object): 15 | def isAnagram(self, s, t): 16 | """ 17 | :type s: str 18 | :type t: str 19 | :rtype: bool 20 | """ 21 | if len(s) != len(t): 22 | return False 23 | d = {} 24 | for c in s: 25 | if c in d: 26 | d[c] += 1 27 | else: 28 | d[c] = 1 29 | for c in t: 30 | if c not in d: 31 | return False 32 | else: 33 | d[c] -= 1 34 | if d[c] < 0: 35 | return False 36 | return True 37 | 38 | 39 | s = Solution() 40 | print(s.isAnagram("aacc", "ccac")) 41 | print(s.isAnagram("abcd", "bcda")) 42 | -------------------------------------------------------------------------------- /valid_palindrome/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a string, determine if it is a palindrome, considering only alphanumeric 3 | characters and ignoring cases. 4 | 5 | For example, 6 | "A man, a plan, a canal: Panama" is a palindrome. 7 | "race a car" is not a palindrome. 8 | 9 | Note: 10 | Have you consider that the string might be empty? This is a good question to 11 | ask during an interview. 12 | 13 | For the purpose of this problem, we define empty string as valid palindrome. 14 | """ 15 | 16 | 17 | class Solution(object): 18 | def isPalindrome(self, s): 19 | """ 20 | :type s: str 21 | :rtype: bool 22 | """ 23 | if not s: 24 | return True 25 | left = 0 26 | right = len(s) - 1 27 | while left < right: 28 | if s[left].isalnum() and s[right].isalnum(): 29 | if s[left].lower() != s[right].lower(): 30 | return False 31 | left += 1 32 | right -= 1 33 | else: 34 | if not s[left].isalnum(): 35 | left += 1 36 | if not s[right].isalnum(): 37 | right -= 1 38 | return True 39 | -------------------------------------------------------------------------------- /valid_parentheses/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a string containing just the characters '(', ')', '{', '}', '[' and ']', 3 | determine if the input string is valid. 4 | 5 | The brackets must close in the correct order, "()" and "()[]{}" are all valid 6 | but "(]" and "([)]" are not. 7 | """ 8 | 9 | 10 | class Solution(object): 11 | def isValid(self, s): 12 | """ 13 | :type s: str 14 | :rtype: bool 15 | """ 16 | pars = { 17 | ')': '(', 18 | ']': '[', 19 | '}': '{', 20 | } 21 | stack = [] 22 | for c in s: 23 | # Left parenthesis 24 | if c not in pars: 25 | stack.append(c) 26 | # Right parenthesis 27 | else: 28 | if stack: 29 | if stack[-1] == pars[c]: 30 | stack.pop() 31 | else: 32 | return False 33 | else: 34 | return False 35 | if stack: 36 | return False 37 | else: 38 | return True 39 | -------------------------------------------------------------------------------- /validate_binary_search_tree/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a binary tree, determine if it is a valid binary search tree (BST). 3 | 4 | Assume a BST is defined as follows: 5 | 6 | The left subtree of a node contains only nodes with keys less than the node's 7 | key. 8 | The right subtree of a node contains only nodes with keys greater than the 9 | node's key. 10 | Both the left and right subtrees must also be binary search trees. 11 | """ 12 | 13 | # Definition for a binary tree node 14 | # class TreeNode: 15 | # def __init__(self, x): 16 | # self.val = x 17 | # self.left = None 18 | # self.right = None 19 | 20 | class Solution: 21 | # @param root, a tree node 22 | # @return a boolean 23 | def isValidBST(self, root): 24 | if root is None: 25 | return True 26 | else: 27 | left = True 28 | right = True 29 | if root.left is not None: 30 | left = (self.max_node(root.left).val < root.val 31 | and self.isValidBST(root.left)) 32 | if root.right is not None: 33 | right = (self.min_node(root.right).val > root.val 34 | and self.isValidBST(root.right)) 35 | if left and right: 36 | return True 37 | return False 38 | 39 | def min_node(self, root): 40 | while root.left is not None: 41 | root = root.left 42 | return root 43 | 44 | def max_node(self, root): 45 | while root.right is not None: 46 | root = root.right 47 | return root 48 | -------------------------------------------------------------------------------- /validate_binary_search_tree/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a binary tree, determine if it is a valid binary search tree (BST). 3 | 4 | Assume a BST is defined as follows: 5 | 6 | The left subtree of a node contains only nodes with keys less than the node's 7 | key. 8 | The right subtree of a node contains only nodes with keys greater than the 9 | node's key. 10 | Both the left and right subtrees must also be binary search trees. 11 | """ 12 | 13 | # Definition for a binary tree node 14 | # class TreeNode: 15 | # def __init__(self, x): 16 | # self.val = x 17 | # self.left = None 18 | # self.right = None 19 | 20 | class Solution: 21 | # @param root, a tree node 22 | # @return a boolean 23 | def isValidBST(self, root): 24 | maxsize = 9223372036854775806 # Assumed sys.maxsize on 64-bit platform 25 | INT_MIN = -maxsize - 1 26 | INT_MAX = maxsize 27 | return self.is_valid_bst_aux(root, INT_MIN, INT_MAX) 28 | 29 | def is_valid_bst_aux(self, root, min_val, max_val): 30 | """Assume that keys are distinct integers""" 31 | if root is None: 32 | return True 33 | if root.val < min_val or root.val > max_val: 34 | return False 35 | # If non-distinct values are allowed, + 1 and - 1 to root.val can be 36 | # removed 37 | is_left_bst = self.is_valid_bst_aux(root.left, min_val, root.val - 1) 38 | is_right_bst = self.is_valid_bst_aux(root.right, root.val + 1, max_val) 39 | return is_left_bst and is_right_bst 40 | -------------------------------------------------------------------------------- /validate_binary_search_tree/solution3.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a binary tree, determine if it is a valid binary search tree (BST). 3 | 4 | Assume a BST is defined as follows: 5 | 6 | The left subtree of a node contains only nodes with keys less than the node's 7 | key. 8 | The right subtree of a node contains only nodes with keys greater than the 9 | node's key. 10 | Both the left and right subtrees must also be binary search trees. 11 | """ 12 | 13 | # Definition for a binary tree node 14 | # class TreeNode: 15 | # def __init__(self, x): 16 | # self.val = x 17 | # self.left = None 18 | # self.right = None 19 | 20 | class Solution: 21 | # @param root, a tree node 22 | # @return a boolean 23 | def isValidBST(self, root): 24 | self.prev = None 25 | return self.is_valid_bst_aux(root) 26 | 27 | def is_valid_bst_aux(self, root): 28 | if root is None: 29 | return True 30 | else: 31 | if not self.is_valid_bst_aux(root.left): 32 | return False 33 | if self.prev is not None: 34 | if self.prev.val >= root.val: 35 | return False 36 | self.prev = root 37 | if not self.is_valid_bst_aux(root.right): 38 | return False 39 | return True 40 | -------------------------------------------------------------------------------- /word_break/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a string s and a dictionary of words dict, determine if s can be 3 | segmented into a space-separated sequence of one or more dictionary words. 4 | 5 | For example, given 6 | s = "leetcode", 7 | dict = ["leet", "code"]. 8 | 9 | Return true because "leetcode" can be segmented as "leet code". 10 | """ 11 | 12 | class Solution(object): 13 | def wordBreak(self, s, wordDict): 14 | """ 15 | :type s: str 16 | :type wordDict: Set[str] 17 | :rtype: bool 18 | """ 19 | n = len(s) 20 | # t[i] indicates s[:i + 1] is such a string 21 | t = [False for i in range(n)] 22 | for i in range(n): 23 | if s[:i + 1] in wordDict: 24 | t[i] = True 25 | else: 26 | for j in range(i): 27 | if t[j] is True and s[j + 1:i + 1] in wordDict: 28 | t[i] = True 29 | break 30 | return t[-1] 31 | -------------------------------------------------------------------------------- /word_break/solution2.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a string s and a dictionary of words dict, determine if s can be 3 | segmented into a space-separated sequence of one or more dictionary words. 4 | 5 | For example, given 6 | s = "leetcode", 7 | dict = ["leet", "code"]. 8 | 9 | Return true because "leetcode" can be segmented as "leet code". 10 | """ 11 | 12 | class Solution(object): 13 | def wordBreak(self, s, wordDict): 14 | """ 15 | :type s: str 16 | :type wordDict: Set[str] 17 | :rtype: bool 18 | """ 19 | n = len(s) 20 | t = [None for i in range(n)] 21 | return self.word_break_aux(s, wordDict, n - 1, t) 22 | 23 | def word_break_aux(self, s, wordDict, i, t): 24 | """ 25 | Determine if s[:i + 1] can be segmented by dict wordDict 26 | """ 27 | if s[:i + 1] in wordDict: 28 | return True 29 | elif t[i] is not None: 30 | return t[i] 31 | else: 32 | for j in range(i): 33 | if (self.word_break_aux(s, wordDict, j, t) is True 34 | and s[j + 1:i + 1] in wordDict): 35 | t[i] = True 36 | return True 37 | else: 38 | t[i] = False 39 | return False 40 | 41 | 42 | s = Solution() 43 | print(s.wordBreak('leetcode', ['leet', 'code'])) 44 | print(s.wordBreak('leetcode', ['lee', 'code'])) 45 | -------------------------------------------------------------------------------- /word_break_ii/solution.py: -------------------------------------------------------------------------------- 1 | """ 2 | Given a string s and a dictionary of words dict, add spaces in s to construct 3 | a sentence where each word is a valid dictionary word. 4 | 5 | Return all such possible sentences. 6 | 7 | For example, given 8 | s = "catsanddog", 9 | dict = ["cat", "cats", "and", "sand", "dog"]. 10 | 11 | A solution is ["cats and dog", "cat sand dog"]. 12 | """ 13 | 14 | class Solution(object): 15 | def wordBreak(self, s, wordDict): 16 | """ 17 | :type s: str 18 | :type wordDict: Set[str] 19 | :rtype: List[str] 20 | 21 | Time Limit Exceeded 22 | """ 23 | cand = [] 24 | res = [] 25 | self.word_break_aux(s, wordDict, cand, res) 26 | return res 27 | 28 | def word_break_aux(self, s, wordDict, cand, res): 29 | """ 30 | Determine if s[:i + 1] can be segmented by dict wordDict 31 | """ 32 | if not s: 33 | res.append(' '.join(cand)) 34 | else: 35 | for i, c in enumerate(s): 36 | word = s[:i + 1] 37 | rest = s[i + 1:] 38 | if word in wordDict: 39 | cand.append(word) 40 | self.word_break_aux(rest, wordDict, cand, res) 41 | cand.pop() 42 | 43 | 44 | s1 = "catsanddog" 45 | d1 = ["cat", "cats", "and", "sand", "dog"] 46 | s = Solution() 47 | print(s.wordBreak(s1, d1)) 48 | -------------------------------------------------------------------------------- /word_ladder/solution2.py: -------------------------------------------------------------------------------- 1 | class Solution: 2 | # @param start, a string 3 | # @param end, a string 4 | # @param dict, a set of string 5 | # @return an integer 6 | def ladderLength(self, start, end, dict): 7 | queue = [] 8 | distance = [] 9 | queue.append(start) 10 | distance.append(1) 11 | # Remove words that are same as start 12 | for word in set(dict): 13 | if start == word: 14 | dict.remove(start) 15 | dict.add(end) 16 | while queue: 17 | cur = queue.pop(0) 18 | d = distance.pop(0) 19 | for word in set(dict): # Iterate over the copy of dict 20 | if self.is_adjacent(cur, word): 21 | dict.remove(word) # Mark as visited 22 | queue.append(word) 23 | if word == end: 24 | return d + 1 25 | distance.append(d + 1) 26 | return 0 27 | 28 | def is_adjacent(self, word1, word2): 29 | count = 0 30 | n = len(word1) 31 | for i in range(n): 32 | if word1[i] != word2[i]: 33 | count += 1 34 | return count == 1 35 | 36 | 37 | s = Solution() 38 | print s.ladderLength("hit", "dow", set(["hot", "dot", "dog", "lot", "log"])) 39 | print s.ladderLength("hit", "cog", set(["hot", "dot", "dog", "lot", "log"])) 40 | --------------------------------------------------------------------------------