diff --git a/Python/01-matrix.py b/Python/01-matrix.py index a4ff877ba..46351da5a 100644 --- a/Python/01-matrix.py +++ b/Python/01-matrix.py @@ -4,7 +4,7 @@ # Given a matrix consists of 0 and 1, find the distance of the nearest 0 for each cell. # The distance between two adjacent cells is 1. # -# Example 1: +# Example 1: # # Input: # 0 0 0 @@ -16,7 +16,7 @@ # 0 1 0 # 0 0 0 # -# Example 2: +# Example 2: # # Input: # 0 0 0 @@ -33,6 +33,9 @@ # There are at least one 0 in the given matrix. # The cells are adjacent in only four directions: up, down, left and right. +import collections + + class Solution(object): def updateMatrix(self, matrix): """ @@ -57,7 +60,7 @@ def updateMatrix(self, matrix): continue queue.append((i, j)) matrix[i][j] = matrix[cell[0]][cell[1]]+1 - + return matrix diff --git a/Python/4sum-ii.py b/Python/4sum-ii.py index 016952602..a11bede5a 100644 --- a/Python/4sum-ii.py +++ b/Python/4sum-ii.py @@ -24,6 +24,9 @@ # 1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0 # 2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0 +import collections + + class Solution(object): def fourSumCount(self, A, B, C, D): """ diff --git a/Python/4sum.py b/Python/4sum.py index d65759bdc..6f137b1ef 100644 --- a/Python/4sum.py +++ b/Python/4sum.py @@ -1,7 +1,7 @@ # Time: O(n^3) # Space: O(1) -# Given an array S of n integers, +# Given an array S of n integers, # are there elements a, b, c, and d in S such that a + b + c + d = target? # Find all unique quadruplets in the array which gives the sum of target. # @@ -16,6 +16,9 @@ # (-2, 0, 0, 2) # +import collections + + # Two pointer solution. (1356ms) class Solution(object): def fourSum(self, nums, target): @@ -62,7 +65,7 @@ def fourSum(self, nums, target): """ nums, result, lookup = sorted(nums), [], collections.defaultdict(list) for i in xrange(0, len(nums) - 1): - for j in xrange(i + 1, len(nums)): + for j in xrange(i + 1, len(nums)): is_duplicated = False for [x, y] in lookup[nums[i] + nums[j]]: if nums[x] == nums[i]: @@ -95,7 +98,7 @@ def fourSum(self, nums, target): """ nums, result, lookup = sorted(nums), [], collections.defaultdict(list) for i in xrange(0, len(nums) - 1): - for j in xrange(i + 1, len(nums)): + for j in xrange(i + 1, len(nums)): lookup[nums[i] + nums[j]].append([i, j]) for i in lookup.keys(): diff --git a/Python/accounts-merge.py b/Python/accounts-merge.py index 3f3a57b40..2eac67d94 100644 --- a/Python/accounts-merge.py +++ b/Python/accounts-merge.py @@ -16,7 +16,7 @@ # The accounts themselves can be returned in any order. # # Example 1: -# Input: +# Input: # accounts = [["John", "johnsmith@mail.com", "john00@mail.com"], # ["John", "johnnybravo@mail.com"], # ["John", "johnsmith@mail.com", "john_newyork@mail.com"], @@ -24,12 +24,12 @@ # Output: [["John", 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com'], # ["John", "johnnybravo@mail.com"], ["Mary", "mary@mail.com"]] # -# Explanation: +# Explanation: # The first and third John's are the same person as they have the common email "johnsmith@mail.com". # The second John and Mary are different people as none of their email addresses are used by other accounts. # We could return these lists in any order, # for example the answer [['Mary', 'mary@mail.com'], -# ['John', 'johnnybravo@mail.com'], +# ['John', 'johnnybravo@mail.com'], # ['John', 'john00@mail.com', 'john_newyork@mail.com', 'johnsmith@mail.com']] # would still be accepted. # @@ -39,6 +39,9 @@ # The length of accounts[i] will be in the range [1, 10]. # The length of accounts[i][j] will be in the range [1, 30]. +import collections + + class UnionFind(object): def __init__(self): self.set = [] @@ -46,7 +49,7 @@ def __init__(self): def get_id(self): self.set.append(len(self.set)) return len(self.set)-1 - + def find_set(self, x): if self.set[x] != x: self.set[x] = self.find_set(self.set[x]) # path compression. diff --git a/Python/add-bold-tag-in-string.py b/Python/add-bold-tag-in-string.py index def3394f3..984d640aa 100644 --- a/Python/add-bold-tag-in-string.py +++ b/Python/add-bold-tag-in-string.py @@ -1,6 +1,9 @@ # Time: O(n * d * l), l is the average string length # Space: O(n) +import collections + + # 59ms class Solution(object): def addBoldTag(self, s, dict): @@ -25,7 +28,7 @@ def addBoldTag(self, s, dict): result.append(""); return "".join(result) - + # Time: O(n * l), l is the average string length # Space: O(t) , t is the size of trie # trie solution, 439ms diff --git a/Python/alien-dictionary.py b/Python/alien-dictionary.py index b9eccb43b..2274736ad 100644 --- a/Python/alien-dictionary.py +++ b/Python/alien-dictionary.py @@ -1,6 +1,14 @@ # Time: O(n) # Space: O(|V|+|E|) = O(26 + 26^2) = O(1) +import collections + +try: + xrange # Python 2 +except NameError: + xrange = range # Python 3 + + # BFS solution. class Solution(object): def alienOrder(self, words): @@ -8,34 +16,35 @@ def alienOrder(self, words): :type words: List[str] :rtype: str """ - result, zero_in_degree_queue, in_degree, out_degree = [], collections.deque(), {}, {} - nodes = sets.Set() + result, in_degree, out_degree = [], {}, {} + zero_in_degree_queue = collections.deque() + nodes = set() for word in words: for c in word: nodes.add(c) - + for i in xrange(1, len(words)): - if len(words[i-1]) > len(words[i]) and \ - words[i-1][:len(words[i])] == words[i]: - return "" + if (len(words[i-1]) > len(words[i]) and + words[i-1][:len(words[i])] == words[i]): + return "" self.findEdges(words[i - 1], words[i], in_degree, out_degree) - + for node in nodes: if node not in in_degree: zero_in_degree_queue.append(node) - + while zero_in_degree_queue: precedence = zero_in_degree_queue.popleft() result.append(precedence) - + if precedence in out_degree: for c in out_degree[precedence]: in_degree[c].discard(precedence) if not in_degree[c]: zero_in_degree_queue.append(c) - + del out_degree[precedence] - + if out_degree: return "" @@ -48,9 +57,9 @@ def findEdges(self, word1, word2, in_degree, out_degree): for i in xrange(str_len): if word1[i] != word2[i]: if word2[i] not in in_degree: - in_degree[word2[i]] = sets.Set() + in_degree[word2[i]] = set() if word1[i] not in out_degree: - out_degree[word1[i]] = sets.Set() + out_degree[word1[i]] = set() in_degree[word2[i]].add(word1[i]) out_degree[word1[i]].add(word2[i]) break @@ -64,16 +73,16 @@ def alienOrder(self, words): :rtype: str """ # Find ancestors of each node by DFS. - nodes, ancestors = sets.Set(), {} + nodes, ancestors = set(), {} for i in xrange(len(words)): for c in words[i]: nodes.add(c) for node in nodes: ancestors[node] = [] for i in xrange(1, len(words)): - if len(words[i-1]) > len(words[i]) and \ - words[i-1][:len(words[i])] == words[i]: - return "" + if (len(words[i-1]) > len(words[i]) and + words[i-1][:len(words[i])] == words[i]): + return "" self.findEdges(words[i - 1], words[i], ancestors) # Output topological order by DFS. @@ -82,7 +91,7 @@ def alienOrder(self, words): for node in nodes: if self.topSortDFS(node, node, ancestors, visited, result): return "" - + return "".join(result) diff --git a/Python/arithmetic-slices-ii-subsequence.py b/Python/arithmetic-slices-ii-subsequence.py index 30418e704..adf5e643e 100644 --- a/Python/arithmetic-slices-ii-subsequence.py +++ b/Python/arithmetic-slices-ii-subsequence.py @@ -42,6 +42,9 @@ # [2,4,6,8,10] # [2,6,10] +import collections + + class Solution(object): def numberOfArithmeticSlices(self, A): """ diff --git a/Python/arranging-coins.py b/Python/arranging-coins.py index f4e3de1df..85d0c868d 100644 --- a/Python/arranging-coins.py +++ b/Python/arranging-coins.py @@ -30,6 +30,9 @@ # # Because the 4th row is incomplete, we return 3. +import math + + class Solution(object): def arrangeCoins(self, n): """ diff --git a/Python/basic-calculator-iv.py b/Python/basic-calculator-iv.py index cdf693a0b..ddb15ab7c 100644 --- a/Python/basic-calculator-iv.py +++ b/Python/basic-calculator-iv.py @@ -15,7 +15,7 @@ # have a leading coefficient or unary operator like "2x" or "-x". # # Expressions are evaluated in the usual order: -# brackets first, then multiplication, then addition and subtraction. +# brackets first, then multiplication, then addition and subtraction. # For example, expression = "1 + 2 * 3" has an answer of ["7"]. # # The format of the output is as follows: @@ -26,9 +26,9 @@ # counting multiplicity. (For example, "a*a*b*c" has degree 4.) # We write the largest degree terms of our answer first, # breaking ties by lexicographic order ignoring the leading coefficient of the term. -# - The leading coefficient of the term is placed directly to the left with an asterisk separating it +# - The leading coefficient of the term is placed directly to the left with an asterisk separating it # from the variables (if they exist.) A leading coefficient of 1 is still printed. -# - An example of a well formatted answer is ["-2*a*a*a", "3*a*a*b", "3*b*b", "4*a", "5*c", "-6"] +# - An example of a well formatted answer is ["-2*a*a*a", "3*a*a*b", "3*b*b", "4*a", "5*c", "-6"] # - Terms (including constant terms) with coefficient 0 are not included. # For example, an expression of "0" has an output of []. # @@ -52,7 +52,7 @@ # # Input: expression = "((a - b) * (b - c) + (c - a)) * ((a - b) + (b - c) * (c - a))", # evalvars = [], evalints = [] -# Output: +# Output: # ["-1*a*a*b*b","2*a*a*b*c","-1*a*a*c*c","1*a*b*b*b","-1*a*b*b*c","-1*a*b*c*c", # "1*a*c*c*c","-1*b*b*b*c","2*b*b*c*c","-1*b*c*c*c","2*a*a*b","-2*a*a*c","-2*a*b*b", # "2*a*c*c","1*b*b*b","-1*b*b*c","1*b*c*c","-1*c*c*c","-1*a*a","1*a*b","1*a*c","-1*b*c"] @@ -61,6 +61,10 @@ # - expression will have length in range [1, 1000]. # - evalvars, evalints will have equal lengths in range [0, 1000]. +import collections +import itertools + + class Poly(collections.Counter): def __init__(self, expr=None): if expr is None: @@ -94,9 +98,9 @@ def merge(k1, k2): i += 1 else: result.append(k2[j]) - j += 1 + j += 1 return result - + result = Poly() for k1, v1 in self.items(): for k2, v2 in other.items(): @@ -119,8 +123,8 @@ def to_list(self): return ["*".join((str(v),) + k) \ for k, v in sorted(self.items(), key=lambda(k, _): (-len(k), k)) \ if v] - - + + class Solution(object): def basicCalculatorIV(self, expression, evalvars, evalints): """ @@ -138,7 +142,7 @@ def compute(operands, operators): operands.append(left - right) elif op == '*': operands.append(left * right) - + def parse(s): if not s: return Poly() @@ -163,6 +167,6 @@ def parse(s): while operators: compute(operands, operators) return operands[-1] - + lookup = dict(itertools.izip(evalvars, evalints)) return parse(expression).eval(lookup).to_list() diff --git a/Python/binary-tree-vertical-order-traversal.py b/Python/binary-tree-vertical-order-traversal.py index 69e483787..6790d59fd 100644 --- a/Python/binary-tree-vertical-order-traversal.py +++ b/Python/binary-tree-vertical-order-traversal.py @@ -8,6 +8,9 @@ # self.left = None # self.right = None +import collections + + # BFS + hash solution. class Solution(object): def verticalOrder(self, root): diff --git a/Python/bold-words-in-string.py b/Python/bold-words-in-string.py index 455e3717f..0f794f228 100644 --- a/Python/bold-words-in-string.py +++ b/Python/bold-words-in-string.py @@ -1,6 +1,9 @@ # Time: O(n * l), n is the length of S, l is the average length of words # Space: O(t) , t is the size of trie +import collections + + class Solution(object): def boldWords(self, words, S): """ diff --git a/Python/brick-wall.py b/Python/brick-wall.py index 47ea1c230..767290085 100644 --- a/Python/brick-wall.py +++ b/Python/brick-wall.py @@ -15,7 +15,7 @@ # in which case the line will obviously cross no bricks. # # Example: -# Input: +# Input: # [[1,2,2,1], # [3,1,2], # [1,3,2], @@ -30,6 +30,9 @@ # The height of wall is in range [1,10,000]. # Total number of bricks of the wall won't exceed 20,000. +import collections + + class Solution(object): def leastBricks(self, wall): """ diff --git a/Python/bulb-switcher.py b/Python/bulb-switcher.py index a63b6c39e..f2dd883dd 100644 --- a/Python/bulb-switcher.py +++ b/Python/bulb-switcher.py @@ -1,27 +1,30 @@ # Time: O(1) # Space: O(1) -# There are n bulbs that are initially off. -# You first turn on all the bulbs. Then, -# you turn off every second bulb. On the -# third round, you toggle every third bulb +# There are n bulbs that are initially off. +# You first turn on all the bulbs. Then, +# you turn off every second bulb. On the +# third round, you toggle every third bulb # (turning on if it's off or turning off if -# it's on). For the nth round, you only -# toggle the last bulb. Find how many bulbs +# it's on). For the nth round, you only +# toggle the last bulb. Find how many bulbs # are on after n rounds. # # Example: # -# Given n = 3. +# Given n = 3. # # At first, the three bulbs are [off, off, off]. # After first round, the three bulbs are [on, on, on]. # After second round, the three bulbs are [on, off, on]. -# After third round, the three bulbs are [on, off, off]. +# After third round, the three bulbs are [on, off, off]. # -# So you should return 1, because there is +# So you should return 1, because there is # only one bulb is on. +import math + + class Solution(object): def bulbSwitch(self, n): """ diff --git a/Python/bulls-and-cows.py b/Python/bulls-and-cows.py index b0c8849f4..ead89679c 100644 --- a/Python/bulls-and-cows.py +++ b/Python/bulls-and-cows.py @@ -3,9 +3,9 @@ # You are playing the following Bulls and Cows game with your friend: # You write a 4-digit secret number and ask your friend to guess it, -# each time your friend guesses a number, you give a hint, the hint -# tells your friend how many digits are in the correct positions -# (called "bulls") and how many digits are in the wrong positions +# each time your friend guesses a number, you give a hint, the hint +# tells your friend how many digits are in the correct positions +# (called "bulls") and how many digits are in the wrong positions # (called "cows"), your friend will use those hints to find out the # secret number. # @@ -15,13 +15,13 @@ # Friend's guess: 7810 # Hint: 1 bull and 3 cows. (The bull is 8, the cows are 0, 1 and 7.) # According to Wikipedia: "Bulls and Cows (also known as Cows and Bulls -# or Pigs and Bulls or Bulls and Cleots) is an old code-breaking mind or -# paper and pencil game for two or more players, predating the similar -# commercially marketed board game Mastermind. The numerical version of -# the game is usually played with 4 digits, but can also be played with +# or Pigs and Bulls or Bulls and Cleots) is an old code-breaking mind or +# paper and pencil game for two or more players, predating the similar +# commercially marketed board game Mastermind. The numerical version of +# the game is usually played with 4 digits, but can also be played with # 3 or any other number of digits." # -# Write a function to return a hint according to the secret number and +# Write a function to return a hint according to the secret number and # friend's guess, use A to indicate the bulls and B to indicate the cows, # in the above example, your function should return 1A3B. # @@ -29,6 +29,9 @@ # digits, and their lengths are always equal. # +import operator + + # One pass solution. from collections import defaultdict from itertools import izip @@ -56,7 +59,7 @@ def getHint(self, secret, guess): B += 1 else: s_lookup[s] += 1 - + return "%dA%dB" % (A, B) @@ -74,4 +77,3 @@ def getHint(self, secret, guess): A = sum(imap(operator.eq, secret, guess)) B = sum((Counter(secret) & Counter(guess)).values()) - A return "%dA%dB" % (A, B) - diff --git a/Python/cheapest-flights-within-k-stops.py b/Python/cheapest-flights-within-k-stops.py index 906bf1fd1..f104bea2c 100644 --- a/Python/cheapest-flights-within-k-stops.py +++ b/Python/cheapest-flights-within-k-stops.py @@ -8,20 +8,20 @@ # If there is no such route, output -1. # # Example 1: -# Input: +# Input: # n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]] # src = 0, dst = 2, k = 1 # Output: 200 -# Explanation: +# Explanation: # The cheapest price from city 0 to city 2 with at most 1 stop costs 200, as marked red in the picture. # # Example 2: -# Input: +# Input: # n = 3, edges = [[0,1,100],[1,2,100],[0,2,500]] # src = 0, dst = 2, k = 0 # Output: 500 # -# Explanation: +# Explanation: # The cheapest price from city 0 to city 2 with at most 0 stop costs 500, as marked blue in the picture. # Note: # - The number of nodes n will be in range [1, 100], with nodes labeled from 0 to n - 1. @@ -31,6 +31,10 @@ # - k is in the range of [0, n - 1]. # - There will not be any duplicated flights or self cycles. +import collections +import heapq + + class Solution(object): def findCheapestPrice(self, n, flights, src, dst, K): """ diff --git a/Python/closest-leaf-in-a-binary-tree.py b/Python/closest-leaf-in-a-binary-tree.py index 839133c9f..1b5c789d7 100644 --- a/Python/closest-leaf-in-a-binary-tree.py +++ b/Python/closest-leaf-in-a-binary-tree.py @@ -58,6 +58,9 @@ # self.left = None # self.right = None +import collections + + class Solution(object): def findClosestLeaf(self, root, k): """ @@ -79,7 +82,7 @@ def traverse(node, neighbors, leaves): neighbors[node.val].append(node.right.val) neighbors[node.right.val].append(node.val) traverse(node.right, neighbors, leaves) - + neighbors, leaves = collections.defaultdict(list), set() traverse(root, neighbors, leaves) q, lookup = [k], set([k]) diff --git a/Python/construct-the-rectangle.py b/Python/construct-the-rectangle.py index 54a412741..400d5f08c 100644 --- a/Python/construct-the-rectangle.py +++ b/Python/construct-the-rectangle.py @@ -15,13 +15,16 @@ # Example: # Input: 4 # Output: [2, 2] -# Explanation: The target area is 4, and all the possible ways to construct it are [1,4], [2,2], [4,1]. +# Explanation: The target area is 4, and all the possible ways to construct it are [1,4], [2,2], [4,1]. # But according to requirement 2, [1,4] is illegal; according to requirement 3, # [4,1] is not optimal compared to [2,2]. So the length L is 2, and the width W is 2. # Note: # The given area won't exceed 10,000,000 and is a positive integer # The web page's width and length you designed must be positive integers. +import math + + class Solution(object): def constructRectangle(self, area): """ diff --git a/Python/contains-duplicate-iii.py b/Python/contains-duplicate-iii.py index 42841b948..778be9eb5 100644 --- a/Python/contains-duplicate-iii.py +++ b/Python/contains-duplicate-iii.py @@ -1,16 +1,20 @@ # Time: O(n * t) # Space: O(max(k, t)) # -# Given an array of integers, find out whether there -# are two distinct inwindowes i and j in the array such -# that the difference between nums[i] and nums[j] is -# at most t and the difference between i and j is at +# Given an array of integers, find out whether there +# are two distinct inwindowes i and j in the array such +# that the difference between nums[i] and nums[j] is +# at most t and the difference between i and j is at # most k. # -# This is not the best solution +# This is not the best solution # since there is no built-in bst structure in Python. # The better solution could be found in C++ solution. + +import collections + + class Solution: # @param {integer[]} nums # @param {integer} k @@ -24,7 +28,7 @@ def containsNearbyAlmostDuplicate(self, nums, k, t): # Make sure window size if len(window) > k: window.popitem(False) - + bucket = n if not t else n // t # At most 2t items. for m in (window.get(bucket - 1), window.get(bucket), window.get(bucket + 1)): diff --git a/Python/course-schedule-ii.py b/Python/course-schedule-ii.py index c7e9c290b..7b9f4d3cf 100644 --- a/Python/course-schedule-ii.py +++ b/Python/course-schedule-ii.py @@ -2,38 +2,41 @@ # Space: O(|E|) # There are a total of n courses you have to take, labeled from 0 to n - 1. -# -# Some courses may have prerequisites, for example to take course 0 you have to first take course 1, +# +# Some courses may have prerequisites, for example to take course 0 you have to first take course 1, # which is expressed as a pair: [0,1] -# -# Given the total number of courses and a list of prerequisite pairs, return the ordering of courses +# +# Given the total number of courses and a list of prerequisite pairs, return the ordering of courses # you should take to finish all courses. -# -# There may be multiple correct orders, you just need to return one of them. If it is impossible +# +# There may be multiple correct orders, you just need to return one of them. If it is impossible # to finish all courses, return an empty array. -# +# # For example: -# +# # 2, [[1,0]] # There are a total of 2 courses to take. To take course 1 you should have finished course 0. # So the correct course order is [0,1] -# +# # 4, [[1,0],[2,0],[3,1],[3,2]] # There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. -# Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is [0,1,2,3]. +# Both courses 1 and 2 should be taken after you finished course 0. So one correct course order is [0,1,2,3]. # Another correct ordering is[0,2,1,3]. -# +# # Note: -# The input prerequisites is a graph represented by a list of edges, not adjacency matrices. +# The input prerequisites is a graph represented by a list of edges, not adjacency matrices. # Read more about how a graph is represented. -# +# # Hints: -# This problem is equivalent to finding the topological order in a directed graph. +# This problem is equivalent to finding the topological order in a directed graph. # If a cycle exists, no topological ordering exists and therefore it will be impossible to take all courses. -# Topological Sort via DFS - A great video tutorial (21 minutes) on Coursera explaining +# Topological Sort via DFS - A great video tutorial (21 minutes) on Coursera explaining # the basic concepts of Topological Sort. # Topological sort could also be done via BFS. -# +# + +import collections + class Solution(object): def findOrder(self, numCourses, prerequisites): @@ -43,7 +46,7 @@ def findOrder(self, numCourses, prerequisites): :rtype: List[int] """ res, zero_in_degree_queue, in_degree, out_degree = [], collections.deque(), {}, {} - + for i, j in prerequisites: if i not in in_degree: in_degree[i] = set() @@ -51,24 +54,24 @@ def findOrder(self, numCourses, prerequisites): out_degree[j] = set() in_degree[i].add(j) out_degree[j].add(i) - + for i in xrange(numCourses): if i not in in_degree: zero_in_degree_queue.append(i) - + while zero_in_degree_queue: prerequisite = zero_in_degree_queue.popleft() res.append(prerequisite) - + if prerequisite in out_degree: for course in out_degree[prerequisite]: in_degree[course].discard(prerequisite) if not in_degree[course]: zero_in_degree_queue.append(course) - + del out_degree[prerequisite] - + if out_degree: return [] - + return res diff --git a/Python/course-schedule-iii.py b/Python/course-schedule-iii.py index af874fc69..605f9cc19 100644 --- a/Python/course-schedule-iii.py +++ b/Python/course-schedule-iii.py @@ -11,13 +11,13 @@ # Example: # Input: [[100, 200], [200, 1300], [1000, 1250], [2000, 3200]] # Output: 3 -# Explanation: +# Explanation: # There're totally 4 courses, but you can take 3 courses at most: # First, take the 1st course, it costs 100 days so you will finish it on the 100th day, # and ready to take the next course on the 101st day. # Second, take the 3rd course, it costs 1000 days so you will finish it on the 1100th day, -# and ready to take the next course on the 1101st day. -# Third, take the 2nd course, it costs 200 days so you will finish it on the 1300th day. +# and ready to take the next course on the 1101st day. +# Third, take the 2nd course, it costs 200 days so you will finish it on the 1300th day. # The 4th course cannot be taken now, since you will finish it on the 3300th day, # which exceeds the closed date. # @@ -25,6 +25,10 @@ # The integer 1 <= d, t, n <= 10,000. # You can't take two courses simultaneously. +import collections +import heapq + + class Solution(object): def scheduleCourse(self, courses): """ diff --git a/Python/custom-sort-string.py b/Python/custom-sort-string.py index 6851fa07e..950760368 100644 --- a/Python/custom-sort-string.py +++ b/Python/custom-sort-string.py @@ -10,12 +10,12 @@ # Return any permutation of T (as a string) that satisfies this property. # # Example : -# Input: +# Input: # S = "cba" # T = "abcd" # Output: "cbad" -# Explanation: -# "a", "b", "c" appear in S, so the order of "a", "b", "c" should be "c", "b", and "a". +# Explanation: +# "a", "b", "c" appear in S, so the order of "a", "b", "c" should be "c", "b", and "a". # Since "d" does not appear in S, it can be at any position in T. "dcba", "cdba", "cbda" are also valid outputs. # # Note: @@ -23,6 +23,9 @@ # - T has length at most 200. # - S and T consist of lowercase letters only. +import collections + + class Solution(object): def customSortString(self, S, T): """ diff --git a/Python/cut-off-trees-for-golf-event.py b/Python/cut-off-trees-for-golf-event.py index b71b21091..e41eaad67 100644 --- a/Python/cut-off-trees-for-golf-event.py +++ b/Python/cut-off-trees-for-golf-event.py @@ -20,7 +20,7 @@ # You are guaranteed that no two trees have the same height and there is at least one tree needs to be cut off. # # Example 1: -# Input: +# Input: # [ # [1,2,3], # [0,0,4], @@ -28,7 +28,7 @@ # ] # Output: 6 # Example 2: -# Input: +# Input: # [ # [1,2,3], # [0,0,0], @@ -36,7 +36,7 @@ # ] # Output: -1 # Example 3: -# Input: +# Input: # [ # [2,3,4], # [0,0,5], @@ -47,11 +47,16 @@ # in (0,0) directly without walking. # Hint: size of the given matrix will not exceed 50x50. -# Solution Reference: +# Solution Reference: # 1. https://discuss.leetcode.com/topic/103532/my-python-solution-inspired-by-a-algorithm/2 # 2. https://discuss.leetcode.com/topic/103562/python-solution-based-on-wufangjie-s-hadlock-s-algorithm # 3. https://en.wikipedia.org/wiki/A*_search_algorithm # 4. https://cg2010studio.files.wordpress.com/2011/12/dijkstra-vs-a-star.png + +import collections +import heapq + + class Solution(object): def cutOffTree(self, forest): """ @@ -127,7 +132,7 @@ def minStep(p1, p2): lookup.add((i, j)) min_steps += 1 return -1 - + m, n = len(forest), len(forest[0]) min_heap = [] for i in xrange(m): diff --git a/Python/degree-of-an-array.py b/Python/degree-of-an-array.py index 567caa282..239c27095 100644 --- a/Python/degree-of-an-array.py +++ b/Python/degree-of-an-array.py @@ -10,7 +10,7 @@ # Example 1: # Input: [1, 2, 2, 3, 1] # Output: 2 -# Explanation: +# Explanation: # The input array has a degree of 2 because both elements 1 and 2 appear twice. # Of the subarrays that have the same degree: # [1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2] @@ -24,6 +24,9 @@ # nums.length will be between 1 and 50,000. # nums[i] will be an integer between 0 and 49,999. +import collections + + class Solution(object): def findShortestSubArray(self, nums): """ @@ -39,4 +42,3 @@ def findShortestSubArray(self, nums): return min(right[num]-left[num]+1 \ for num in counts.keys() \ if counts[num] == degree) - diff --git a/Python/design-compressed-string-iterator.py b/Python/design-compressed-string-iterator.py index 162840d79..e23233aa9 100644 --- a/Python/design-compressed-string-iterator.py +++ b/Python/design-compressed-string-iterator.py @@ -1,6 +1,9 @@ # Time: O(1) # Space: O(1) +import re + + class StringIterator(object): def __init__(self, compressedString): @@ -22,14 +25,14 @@ def next(self): self.__index += 1 self.__num -= 1 return self.__ch - + def hasNext(self): """ :rtype: bool """ return self.__index != len(self.__result) or self.__num != 0 - + # Your StringIterator object will be instantiated and called as such: diff --git a/Python/design-excel-sum-formula.py b/Python/design-excel-sum-formula.py index 24a1b47ca..edd5df557 100644 --- a/Python/design-excel-sum-formula.py +++ b/Python/design-excel-sum-formula.py @@ -3,6 +3,9 @@ # sum: O((r * c)^2) # Space: O(r * c) +import collections + + class Excel(object): def __init__(self, H, W): @@ -14,7 +17,7 @@ def __init__(self, H, W): for _ in xrange(H+1)] self.__fward = collections.defaultdict(lambda : collections.defaultdict(int)) self.__bward = collections.defaultdict(set) - + def set(self, r, c, v): """ @@ -25,7 +28,7 @@ def set(self, r, c, v): """ self.__reset_dependency(r, c); self.__update_others(r, c, v); - + def get(self, r, c): """ @@ -34,7 +37,7 @@ def get(self, r, c): :rtype: int """ return self.__exl[r][ord(c) - ord('A')] - + def sum(self, r, c, strs): """ diff --git a/Python/design-search-autocomplete-system.py b/Python/design-search-autocomplete-system.py index f7a4d04b7..cc540a426 100644 --- a/Python/design-search-autocomplete-system.py +++ b/Python/design-search-autocomplete-system.py @@ -1,7 +1,10 @@ # Time: O(p^2), p is the length of the prefix # Space: O(p * t + s), t is the number of nodes of trie # , s is the size of the sentences - + +import collections + + class TrieNode(object): def __init__(self): @@ -19,7 +22,7 @@ def insert(self, s, times): cur = cur.leaves[c] cur.add_info(s, times) - + def add_info(self, s, times): for p in self.infos: if p[1] == s: @@ -68,7 +71,7 @@ def input(self, c): self.__cur_node = self.__cur_node.leaves[c] result = [p[1] for p in self.__cur_node.infos] return result - + # Your AutocompleteSystem object will be instantiated and called as such: # obj = AutocompleteSystem(sentences, times) diff --git a/Python/design-snake-game.py b/Python/design-snake-game.py index 134dbcae3..f0792ac15 100644 --- a/Python/design-snake-game.py +++ b/Python/design-snake-game.py @@ -1,7 +1,7 @@ # Time: O(1) per move # Space: O(s), s is the current length of the snake. -from collections import deque +from collections import defaultdict, deque class SnakeGame(object): @@ -9,7 +9,7 @@ def __init__(self, width,height,food): """ Initialize your data structure here. @param width - screen width - @param height - screen height + @param height - screen height @param food - A list of food positions E.g food = [[1,1], [1,0]] means the first food is positioned at [1,1], the second is at [1,0]. :type width: int @@ -21,15 +21,15 @@ def __init__(self, width,height,food): self.__score = 0 self.__food = deque(food) self.__snake = deque([(0, 0)]) - self.__direction = {"U":(-1, 0), "L":(0, -1), "R":(0, 1), "D":(1, 0)}; - self.__lookup = collections.defaultdict(int) + self.__direction = {"U": (-1, 0), "L": (0, -1), "R": (0, 1), "D": (1, 0)} + self.__lookup = defaultdict(int) self.__lookup[(0, 0)] += 1 - + def move(self, direction): """ Moves the snake. - @param direction - 'U' = Up, 'L' = Left, 'R' = Right, 'D' = Down - @return The game's score after the move. Return -1 if game over. + @param direction - 'U' = Up, 'L' = Left, 'R' = Right, 'D' = Down + @return The game's score after the move. Return -1 if game over. Game over when snake crosses the screen boundary or bites its body. :type direction: str :rtype: int diff --git a/Python/design-tic-tac-toe.py b/Python/design-tic-tac-toe.py index cf4b1384f..b5f6d0aac 100644 --- a/Python/design-tic-tac-toe.py +++ b/Python/design-tic-tac-toe.py @@ -1,6 +1,12 @@ # Time: O(1), per move. # Space: O(n^2) +try: + xrange # Python 2 +except NameError: + xrange = range # Python 3 + + class TicTacToe(object): def __init__(self, n): @@ -13,7 +19,6 @@ def __init__(self, n): self.__cols = [[0, 0] for _ in xrange(n)] self.__diagonal = [0, 0] self.__anti_diagonal = [0, 0] - def move(self, row, col, player): """ @@ -37,10 +42,10 @@ def move(self, row, col, player): self.__diagonal[i] += 1 if col == len(self.__rows) - row - 1: self.__anti_diagonal[i] += 1 - if any([self.__rows[row][i] == self.__size), \ - self.__cols[col][i] == self.__size, \ - self.__diagonal[i] == self.__size, \ - self.__anti_diagonal[i] == self.__size]): + if any(self.__rows[row][i] == self.__size, + self.__cols[col][i] == self.__size, + self.__diagonal[i] == self.__size, + self.__anti_diagonal[i] == self.__size): return player return 0 diff --git a/Python/design-twitter.py b/Python/design-twitter.py index 8fe5ee95a..ed03792da 100644 --- a/Python/design-twitter.py +++ b/Python/design-twitter.py @@ -40,6 +40,10 @@ # // since user 1 is no longer following user 2. # twitter.getNewsFeed(1); +import collections +import heapq + + class Twitter(object): def __init__(self): diff --git a/Python/different-ways-to-add-parentheses.py b/Python/different-ways-to-add-parentheses.py index b83604fbf..c88602a20 100644 --- a/Python/different-ways-to-add-parentheses.py +++ b/Python/different-ways-to-add-parentheses.py @@ -1,4 +1,4 @@ -# Time: O(n * 4^n / n^(3/2)) ~= n * Catalan numbers = n * (C(2n, n) - C(2n, n - 1)), +# Time: O(n * 4^n / n^(3/2)) ~= n * Catalan numbers = n * (C(2n, n) - C(2n, n - 1)), # due to the size of the results is Catalan numbers, # and every way of evaluation is the length of the string, # so the time complexity is at most n * Catalan numbers. @@ -28,6 +28,10 @@ # Output: [-34, -14, -10, -10, 10] # +import operator +import re + + class Solution: # @param {string} input # @return {integer[]} @@ -36,7 +40,7 @@ def diffWaysToCompute(self, input): nums = map(int, tokens[::2]) ops = map({'+': operator.add, '-': operator.sub, '*': operator.mul}.get, tokens[1::2]) lookup = [[None for _ in xrange(len(nums))] for _ in xrange(len(nums))] - + def diffWaysToComputeRecu(left, right): if left == right: return [nums[left]] @@ -47,7 +51,7 @@ def diffWaysToComputeRecu(left, right): for x in diffWaysToComputeRecu(left, i) for y in diffWaysToComputeRecu(i + 1, right)] return lookup[left][right] - + return diffWaysToComputeRecu(0, len(nums) - 1) class Solution2: @@ -66,10 +70,10 @@ def diffWaysToComputeRecu(left, right): for x in diffWaysToComputeRecu(left, i): for y in diffWaysToComputeRecu(i + 1, right): result.append(ops[input[i]](x, y)) - + if not result: result = [int(input[left:right])] - lookup[left][right] = result + lookup[left][right] = result return lookup[left][right] - + return diffWaysToComputeRecu(0, len(input)) diff --git a/Python/domino-and-tromino-tiling.py b/Python/domino-and-tromino-tiling.py index a7919a81b..401104ef0 100644 --- a/Python/domino-and-tromino-tiling.py +++ b/Python/domino-and-tromino-tiling.py @@ -17,7 +17,7 @@ # Example: # Input: 3 # Output: 5 -# Explanation: +# Explanation: # The five different ways are listed below, different letters indicates different tiles: # XYZ XXZ XYY XXY XYY # XYZ YYZ XZZ XYY XXY @@ -25,6 +25,9 @@ # Note: # - N will be in range [1, 1000]. +import itertools + + class Solution(object): def numTilings(self, N): """ @@ -43,7 +46,7 @@ def matrix_expo(A, K): return matrix_mult(matrix_expo(A, K-1), A) B = matrix_expo(A, K//2) return matrix_mult(B, B) - + def matrix_mult(A, B): ZB = zip(*B) return [[sum(a*b for a, b in itertools.izip(row, col)) % M \ @@ -76,4 +79,3 @@ def numTilings(self, N): for i in xrange(3, N+1): dp[i%3] = (2*dp[(i-1)%3]%M + dp[(i-3)%3])%M return dp[N%3] - diff --git a/Python/dota2-senate.py b/Python/dota2-senate.py index bbed007e5..38d55d6bc 100644 --- a/Python/dota2-senate.py +++ b/Python/dota2-senate.py @@ -8,9 +8,9 @@ # The voting for this change is a round-based procedure. # In each round, each senator can exercise one of the two rights: # -# Ban one senator's right: +# Ban one senator's right: # A senator can make another senator lose all his rights in this and all the following rounds. -# Announce the victory: +# Announce the victory: # If this senator found the senators who still have rights to vote are all from the same party, # he can announce the victory and make the decision about the change in the game. # @@ -29,20 +29,23 @@ # Example 1: # Input: "RD" # Output: "Radiant" -# Explanation: The first senator comes from Radiant and he can just ban the next senator's right in the round 1. -# And the second senator can't exercise any rights any more since his right has been banned. +# Explanation: The first senator comes from Radiant and he can just ban the next senator's right in the round 1. +# And the second senator can't exercise any rights any more since his right has been banned. # And in the round 2, the first senator can just announce the victory since he is the only guy in the senate who can vote. # Example 2: # Input: "RDD" # Output: "Dire" -# Explanation: -# The first senator comes from Radiant and he can just ban the next senator's right in the round 1. -# And the second senator can't exercise any rights anymore since his right has been banned. -# And the third senator comes from Dire and he can ban the first senator's right in the round 1. +# Explanation: +# The first senator comes from Radiant and he can just ban the next senator's right in the round 1. +# And the second senator can't exercise any rights anymore since his right has been banned. +# And the third senator comes from Dire and he can ban the first senator's right in the round 1. # And in the round 2, the third senator can just announce the victory since he is the only guy in the senate who can vote. # Note: # The length of the given string will in the range [1, 10,000]. +import collections + + class Solution(object): def predictPartyVictory(self, senate): """ diff --git a/Python/employee-free-time.py b/Python/employee-free-time.py index e2f0779a1..6fe120844 100644 --- a/Python/employee-free-time.py +++ b/Python/employee-free-time.py @@ -33,6 +33,9 @@ # self.start = s # self.end = e +import heapq + + class Solution(object): def employeeFreeTime(self, schedule): """ diff --git a/Python/employee-importance.py b/Python/employee-importance.py index 92bab697b..06cf9d5da 100644 --- a/Python/employee-importance.py +++ b/Python/employee-importance.py @@ -26,6 +26,9 @@ # One employee has at most one direct leader and may have several subordinates. # The maximum number of employees won't exceed 2000. +import collections + + """ # Employee info class Employee(object): diff --git a/Python/encode-and-decode-tinyurl.py b/Python/encode-and-decode-tinyurl.py index 5bfe41982..8217902e4 100644 --- a/Python/encode-and-decode-tinyurl.py +++ b/Python/encode-and-decode-tinyurl.py @@ -10,6 +10,8 @@ # You just need to ensure that a URL can be encoded to a tiny URL # and the tiny URL can be decoded to the original URL. +import random + class Codec: def __init__(self): @@ -20,7 +22,7 @@ def __init__(self): def encode(self, longUrl): """Encodes a URL to a shortened URL. - + :type longUrl: str :rtype: str """ @@ -29,7 +31,7 @@ def getRand(): for _ in xrange(self.__random_length): rand += self.__alphabet[random.randint(0, len(self.__alphabet)-1)] return "".join(rand) - + key = getRand() while key in self.__lookup: key = getRand() @@ -38,7 +40,7 @@ def getRand(): def decode(self, shortUrl): """Decodes a shortened URL to its original URL. - + :type shortUrl: str :rtype: str """ diff --git a/Python/equal-tree-partition.py b/Python/equal-tree-partition.py index 7f77d97a4..52476fa96 100644 --- a/Python/equal-tree-partition.py +++ b/Python/equal-tree-partition.py @@ -8,6 +8,9 @@ # self.left = None # self.right = None +import collections + + class Solution(object): def checkEqualTree(self, root): """ diff --git a/Python/erect-the-fence.py b/Python/erect-the-fence.py index c1ffe423d..47dde4d13 100644 --- a/Python/erect-the-fence.py +++ b/Python/erect-the-fence.py @@ -15,7 +15,7 @@ # Input: [[1,2],[2,2],[4,2]] # Output: [[1,2],[2,2],[4,2]] # -# Even you only have trees in a line, you need to use rope to enclose them. +# Even you only have trees in a line, you need to use rope to enclose them. # Note: # # All trees should be enclosed together. @@ -31,6 +31,9 @@ # self.x = a # self.y = b +import itertools + + # Monotone Chain Algorithm class Solution(object): def outerTrees(self, points): diff --git a/Python/evaluate-division.py b/Python/evaluate-division.py index bf1399601..0a46fadd4 100644 --- a/Python/evaluate-division.py +++ b/Python/evaluate-division.py @@ -8,21 +8,24 @@ # If the answer does not exist, return -1.0. # # Example: -# Given a / b = 2.0, b / c = 3.0. -# queries are: a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ? . +# Given a / b = 2.0, b / c = 3.0. +# queries are: a / c = ?, b / a = ?, a / e = ?, a / a = ?, x / x = ? . # return [6.0, 0.5, -1.0, 1.0, -1.0 ]. # # The input is: # vector> euqations, vector& values, vector> query . # # where equations.size() == values.size(),the values are positive. -# this represents the equations.return vector. . +# this represents the equations.return vector. . # The example above: equations = [ ["a", "b"], ["b", "c"] ]. # values = [2.0, 3.0]. queries = [ ["a", "c"], ["b", "a"], ["a", "e"], ["a", "a"], ["x", "x"] ]. # # The input is always valid. You may assume that # evaluating the queries will result in no division by zero and there is no contradiction. +import collections + + class Solution(object): def calcEquation(self, equations, values, query): """ diff --git a/Python/falling-squares.py b/Python/falling-squares.py index 13bb1c82b..d834723fd 100644 --- a/Python/falling-squares.py +++ b/Python/falling-squares.py @@ -3,7 +3,7 @@ # On an infinite number line (x-axis), we drop given squares in the order they are given. # -# The i-th square dropped (positions[i] = (left, side_length)) is a square +# The i-th square dropped (positions[i] = (left, side_length)) is a square # with the left-most point being positions[i][0] and sidelength positions[i][1]. # # The square is dropped with the bottom edge parallel to the number line, @@ -22,14 +22,14 @@ # Output: [2, 5, 5] # Explanation: # -# After the first drop of +# After the first drop of # positions[0] = [1, 2]: # _aa # _aa # ------- # The maximum height of any square is 2. # -# After the second drop of +# After the second drop of # positions[1] = [2, 3]: # __aaa # __aaa @@ -37,11 +37,11 @@ # _aa__ # _aa__ # -------------- -# The maximum height of any square is 5. +# The maximum height of any square is 5. # The larger square stays on top of the smaller square despite where its center # of gravity is, because squares are infinitely sticky on their bottom edge. # -# After the third drop of +# After the third drop of # positions[1] = [6, 1]: # __aaa # __aaa @@ -51,7 +51,7 @@ # -------------- # The maximum height of any square is still 5. # -# Thus, we return an answer of +# Thus, we return an answer of # [2, 5, 5] # . # @@ -65,6 +65,9 @@ # 1 <= positions[0] <= 10^8. # 1 <= positions[1] <= 10^6. +import bisect + + class SegmentTree(object): def __init__(self, N, update_fn, query_fn): self.N = N @@ -187,7 +190,7 @@ def update(heights, left, right, B, blocks, blocks_read, h): heights = [0] * W blocks = [0] * (B+2) blocks_read = [0] * (B+2) - + max_height = 0 result = [] for left, size in positions: diff --git a/Python/find-anagram-mappings.py b/Python/find-anagram-mappings.py index c113d42a0..69a2bf25d 100644 --- a/Python/find-anagram-mappings.py +++ b/Python/find-anagram-mappings.py @@ -22,6 +22,9 @@ # - A, B have equal lengths in range [1, 100]. # - A[i], B[i] are integers in range [0, 10^5]. +import collections + + class Solution(object): def anagramMappings(self, A, B): """ diff --git a/Python/find-duplicate-file-in-system.py b/Python/find-duplicate-file-in-system.py index 34e36011e..d0b2fb0dd 100644 --- a/Python/find-duplicate-file-in-system.py +++ b/Python/find-duplicate-file-in-system.py @@ -12,12 +12,12 @@ # # "root/d1/d2/.../dm f1.txt(f1_content) f2.txt(f2_content) ... fn.txt(fn_content)" # -# It means there are n files (f1.txt, f2.txt ... fn.txt +# It means there are n files (f1.txt, f2.txt ... fn.txt # with content f1_content, f2_content ... fn_content, respectively) in # directory root/d1/d2/.../dm. Note that n >= 1 and m >= 0. If m = 0, it means the directory is just the root directory. # -# The output is a list of group of duplicate file paths. For each group, -# it contains all the file paths of the files that have the same content. +# The output is a list of group of duplicate file paths. For each group, +# it contains all the file paths of the files that have the same content. # A file path is a string that has the following format: # # "directory_path/file_name.txt" @@ -25,7 +25,7 @@ # Example 1: # Input: # ["root/a 1.txt(abcd) 2.txt(efgh)", "root/c 3.txt(abcd)", "root/c/d 4.txt(efgh)", "root 4.txt(efgh)"] -# Output: +# Output: # [["root/a/2.txt","root/c/d/4.txt","root/4.txt"],["root/a/1.txt","root/c/3.txt"]] # Note: # No order is required for the final output. @@ -45,6 +45,9 @@ # What is the most time-consuming part and memory consuming part of it? How to optimize? # 5. How to make sure the duplicated files you find are not false positive? +import collections + + class Solution(object): def findDuplicate(self, paths): """ diff --git a/Python/find-duplicate-subtrees.py b/Python/find-duplicate-subtrees.py index 2ec2552c2..8c75ca059 100644 --- a/Python/find-duplicate-subtrees.py +++ b/Python/find-duplicate-subtrees.py @@ -6,7 +6,7 @@ # # Two trees are duplicate if they have the same structure with same node values. # -# Example 1: +# Example 1: # 1 # / \ # 2 3 @@ -29,6 +29,9 @@ # self.left = None # self.right = None +import collections + + class Solution(object): def findDuplicateSubtrees(self, root): """ @@ -68,7 +71,7 @@ def postOrderTraversal(node, lookup, result): result.append(node) lookup[s] += 1 return s - + lookup = collections.defaultdict(int) result = [] postOrderTraversal(root, lookup, result) diff --git a/Python/find-eventual-safe-states.py b/Python/find-eventual-safe-states.py index 3edc7cb32..48455c8a4 100644 --- a/Python/find-eventual-safe-states.py +++ b/Python/find-eventual-safe-states.py @@ -23,6 +23,9 @@ # - The number of edges in the graph will not exceed 32000. # - Each graph[i] will be a sorted list of different integers, chosen within the range [0, graph.length - 1]. +import collections + + class Solution(object): def eventualSafeNodes(self, graph): """ @@ -30,7 +33,7 @@ def eventualSafeNodes(self, graph): :rtype: List[int] """ WHITE, GRAY, BLACK = 0, 1, 2 - + def dfs(graph, node, lookup): if lookup[node] != WHITE: return lookup[node] == BLACK diff --git a/Python/find-k-closest-elements.py b/Python/find-k-closest-elements.py index d983de952..232df2879 100644 --- a/Python/find-k-closest-elements.py +++ b/Python/find-k-closest-elements.py @@ -16,6 +16,9 @@ # Length of the given array is positive and will not exceed 10^4 # Absolute value of elements in the array and x will not exceed 10^4 +import bisect + + class Solution(object): def findClosestElements(self, arr, k, x): """ diff --git a/Python/find-right-interval.py b/Python/find-right-interval.py index 8c1a9a9a2..4e00fb8d0 100644 --- a/Python/find-right-interval.py +++ b/Python/find-right-interval.py @@ -41,6 +41,9 @@ # self.start = s # self.end = e +import bisect + + class Solution(object): def findRightInterval(self, intervals): """ diff --git a/Python/find-smallest-letter-greater-than-target.py b/Python/find-smallest-letter-greater-than-target.py index 0f8fc0c37..2e20c9ad1 100644 --- a/Python/find-smallest-letter-greater-than-target.py +++ b/Python/find-smallest-letter-greater-than-target.py @@ -41,6 +41,9 @@ # - letters consists of lowercase letters, and contains at least 2 unique letters. # - target is a lowercase letter. +import bisect + + class Solution(object): def nextGreatestLetter(self, letters, target): """ diff --git a/Python/flip-game-ii.py b/Python/flip-game-ii.py index 79cc4b979..4135d1b7e 100644 --- a/Python/flip-game-ii.py +++ b/Python/flip-game-ii.py @@ -1,6 +1,10 @@ # Time: O(n + c^2) # Space: O(c) +import itertools +import re + + # The best theory solution (DP, O(n + c^2)) could be seen here: # https://leetcode.com/discuss/64344/theory-matters-from-backtracking-128ms-to-dp-0m class Solution(object): diff --git a/Python/fraction-addition-and-subtraction.py b/Python/fraction-addition-and-subtraction.py index cd51acb8e..f2ac5ecb0 100644 --- a/Python/fraction-addition-and-subtraction.py +++ b/Python/fraction-addition-and-subtraction.py @@ -30,6 +30,9 @@ # The number of given fractions will be in the range [1,10]. # The numerator and denominator of the final result are guaranteed to be valid and in the range of 32-bit int. +import re + + class Solution(object): def fractionAddition(self, expression): """ diff --git a/Python/freedom-trail.py b/Python/freedom-trail.py index 227b48c74..c7d1a9bb2 100644 --- a/Python/freedom-trail.py +++ b/Python/freedom-trail.py @@ -12,7 +12,7 @@ # Initially, the first character of the ring is aligned at 12:00 direction. # You need to spell all the characters in the string key one by one # by rotating the ring clockwise or anticlockwise to make each character of -# the string key aligned at 12:00 direction and then by pressing the center button. +# the string key aligned at 12:00 direction and then by pressing the center button. # At the stage of rotating the ring to spell the key character key[i]: # You can rotate the ring clockwise or anticlockwise one place, which counts as 1 step. # The final purpose of the rotation is to align one of the string ring's @@ -26,7 +26,7 @@ # Input: ring = "godding", key = "gd" # Output: 4 # Explanation: -# For the first key character 'g', since it is already in place, we just need 1 step to spell this character. +# For the first key character 'g', since it is already in place, we just need 1 step to spell this character. # For the second key character 'd', # we need to rotate the ring "godding" anticlockwise by two steps to make it become "ddinggo". # Also, we need 1 more step for spelling. @@ -36,6 +36,9 @@ # There are only lowercase letters in both strings and might be some duplcate characters in both strings. # It's guaranteed that string key could always be spelled by rotating the string ring. +import collections + + class Solution(object): def findRotateSteps(self, ring, key): """ @@ -46,7 +49,7 @@ def findRotateSteps(self, ring, key): lookup = collections.defaultdict(list) for i in xrange(len(ring)): lookup[ring[i]].append(i) - + dp = [[0] * len(ring) for _ in xrange(2)] prev = [0] for i in xrange(1, len(key)+1): diff --git a/Python/graph-valid-tree.py b/Python/graph-valid-tree.py index 50c5ababc..7e0be8344 100644 --- a/Python/graph-valid-tree.py +++ b/Python/graph-valid-tree.py @@ -1,6 +1,9 @@ # Time: O(|V| + |E|) # Space: O(|V| + |E|) +import collections + + # BFS solution. Same complexity but faster version. class Solution(object): # @param {integer} n diff --git a/Python/group-anagrams.py b/Python/group-anagrams.py index 7b4ff9628..f1a51e789 100644 --- a/Python/group-anagrams.py +++ b/Python/group-anagrams.py @@ -6,6 +6,9 @@ # Note: All inputs will be in lower-case. # +import collections + + class Solution(object): def groupAnagrams(self, strs): """ diff --git a/Python/group-shifted-strings.py b/Python/group-shifted-strings.py index 53259c496..9f58ee361 100644 --- a/Python/group-shifted-strings.py +++ b/Python/group-shifted-strings.py @@ -1,6 +1,9 @@ # Time: O(nlogn) # Space: O(n) +import collections + + class Solution: # @param {string[]} strings # @return {string[][]} @@ -12,7 +15,7 @@ def groupStrings(self, strings): result = [] for key, val in groups.iteritems(): result.append(sorted(val)) - + return result def hashStr(self, s): diff --git a/Python/heaters.py b/Python/heaters.py index 65de830f7..c2f8cdecd 100644 --- a/Python/heaters.py +++ b/Python/heaters.py @@ -26,6 +26,9 @@ # Explanation: The two heater was placed in the position 1 and 4. We need to use radius 1 standard, # then all the houses can be warmed. +import bisect + + class Solution(object): def findRadius(self, houses, heaters): """ @@ -45,4 +48,3 @@ def findRadius(self, houses, heaters): curr_radius = min(curr_radius, house - heaters[smaller]) min_radius = max(min_radius, curr_radius) return min_radius - diff --git a/Python/implement-magic-dictionary.py b/Python/implement-magic-dictionary.py index d7785e595..7dd43640c 100644 --- a/Python/implement-magic-dictionary.py +++ b/Python/implement-magic-dictionary.py @@ -22,6 +22,9 @@ # Please remember to RESET your class variables declared in class MagicDictionary, # as static/class variables are persisted across multiple test cases. Please see here for more details. +import collections + + class MagicDictionary(object): def __init__(self): @@ -48,22 +51,22 @@ def search(self, word): :type word: str :rtype: bool """ - def find(word, curr, i, mistakeAllowed): + def find(word, curr, i, mistakeAllowed): if i == len(word): return "_end" in curr and not mistakeAllowed - if word[i] not in curr: + if word[i] not in curr: return any(find(word, curr[c], i+1, False) for c in curr if c != "_end") \ - if mistakeAllowed else False - - if mistakeAllowed: + if mistakeAllowed else False + + if mistakeAllowed: return find(word, curr[word[i]], i+1, True) or \ any(find(word, curr[c], i+1, False) \ for c in curr if c not in ("_end", word[i])) return find(word, curr[word[i]], i+1, False) - return find(word, self.trie, 0, True) - + return find(word, self.trie, 0, True) + # Your MagicDictionary object will be instantiated and called as such: diff --git a/Python/implement-stack-using-queues.py b/Python/implement-stack-using-queues.py index 05ec228d6..8713e606f 100644 --- a/Python/implement-stack-using-queues.py +++ b/Python/implement-stack-using-queues.py @@ -16,24 +16,26 @@ # queue), as long as you use only standard operations of a queue. # You may assume that all operations are valid (for example, no pop # or top operations will be called on an empty stack). -# + +import collections + class Queue: def __init__(self): self.data = collections.deque() - + def push(self, x): self.data.append(x) - + def peek(self): return self.data[0] - + def pop(self): return self.data.popleft() - + def size(self): return len(self.data) - + def empty(self): return len(self.data) == 0 diff --git a/Python/increasing-triplet-subsequence.py b/Python/increasing-triplet-subsequence.py index da1e27ccb..e5a940433 100644 --- a/Python/increasing-triplet-subsequence.py +++ b/Python/increasing-triplet-subsequence.py @@ -1,12 +1,12 @@ # Time: O(n) # Space: O(1) -# Given an unsorted array return whether an increasing +# Given an unsorted array return whether an increasing # subsequence of length 3 exists or not in the array. # Formally the function should: -# Return true if there exists i, j, k -# such that arr[i] < arr[j] < arr[k] +# Return true if there exists i, j, k +# such that arr[i] < arr[j] < arr[k] # given 0 <= i < j < k <= n-1 else return false. # Your algorithm should run in O(n) time complexity and O(1) space complexity. @@ -17,6 +17,8 @@ # Given [5, 4, 3, 2, 1], # return false. +import bisect + class Solution(object): def increasingTriplet(self, nums): diff --git a/Python/invert-binary-tree.py b/Python/invert-binary-tree.py index 5c62fd73f..18b38c497 100644 --- a/Python/invert-binary-tree.py +++ b/Python/invert-binary-tree.py @@ -18,26 +18,30 @@ # Time: O(n) # Space: O(w), w is the max number of the nodes of the levels. + +import collections + + # BFS solution. class Queue: def __init__(self): self.data = collections.deque() - + def push(self, x): self.data.append(x) - + def peek(self): return self.data[0] - + def pop(self): return self.data.popleft() - + def size(self): return len(self.data) - + def empty(self): return len(self.data) == 0 - + # Definition for a binary tree node. # class TreeNode: # def __init__(self, x): @@ -59,9 +63,9 @@ def invertTree(self, root): nodes.push(node.left) if node.right is not None: nodes.push(node.right) - + return root - + # Time: O(n) # Space: O(h) # Stack solution. @@ -79,9 +83,9 @@ def invertTree(self, root): nodes.append(node.left) if node.right is not None: nodes.append(node.right) - + return root - + # Time: O(n) # Space: O(h) # DFS, Recursive solution. @@ -92,5 +96,5 @@ def invertTree(self, root): if root is not None: root.left, root.right = self.invertTree(root.right), \ self.invertTree(root.left) - + return root diff --git a/Python/ipo.py b/Python/ipo.py index ef1b99102..dffd3caf4 100644 --- a/Python/ipo.py +++ b/Python/ipo.py @@ -28,6 +28,9 @@ # The length of Profits array and Capital array will not exceed 50,000. # The answer is guaranteed to fit in a 32-bit signed integer. +import heapq + + class Solution(object): def findMaximizedCapital(self, k, W, Profits, Capital): """ diff --git a/Python/kill-process.py b/Python/kill-process.py index 88b0e0867..4eb4695ce 100644 --- a/Python/kill-process.py +++ b/Python/kill-process.py @@ -1,6 +1,9 @@ # Time: O(n) # Space: O(n) +import collections + + # DFS solution. class Solution(object): def killProcess(self, pid, ppid, kill): diff --git a/Python/lfu-cache.py b/Python/lfu-cache.py index 97a153540..8812da57b 100644 --- a/Python/lfu-cache.py +++ b/Python/lfu-cache.py @@ -4,7 +4,7 @@ # Design and implement a data structure for Least Frequently Used (LFU) cache. # It should support the following operations: get and put. # -# get(key) - Get the value (will always be positive) of the key +# get(key) - Get the value (will always be positive) of the key # if the key exists in the cache, otherwise return -1. # put(key, value) - Set or insert the value if the key is not already present. # When the cache reaches its capacity, @@ -31,6 +31,9 @@ # cache.get(3); // returns 3 # cache.get(4); // returns 4 +import collections + + class ListNode(object): def __init__(self, key, value, freq): self.key = key @@ -44,7 +47,7 @@ class LinkedList(object): def __init__(self): self.head = None self.tail = None - + def append(self, node): node.next, node.prev = None, None # avoid dirty node if self.head is None: @@ -53,7 +56,7 @@ def append(self, node): self.tail.next = node node.prev = self.tail self.tail = node - + def delete(self, node): if node.prev: node.prev.next = node.next @@ -99,7 +102,7 @@ def get(self, key): self.__freq_to_nodes[self.__key_to_node[key].freq].append(self.__key_to_node[key]) return self.__key_to_node[key].val - + def put(self, key, value): """ @@ -113,14 +116,14 @@ def put(self, key, value): if self.get(key) != -1: self.__key_to_node[key].val = value return - + if self.__size == self.__capa: del self.__key_to_node[self.__freq_to_nodes[self.__min_freq].head.key] self.__freq_to_nodes[self.__min_freq].delete(self.__freq_to_nodes[self.__min_freq].head) if not self.__freq_to_nodes[self.__min_freq].head: del self.__freq_to_nodes[self.__min_freq] self.__size -= 1 - + self.__min_freq = 1 self.__key_to_node[key] = ListNode(key, value, self.__min_freq) self.__freq_to_nodes[self.__key_to_node[key].freq].append(self.__key_to_node[key]) diff --git a/Python/line-reflection.py b/Python/line-reflection.py index 2d508e2e4..9929b8371 100644 --- a/Python/line-reflection.py +++ b/Python/line-reflection.py @@ -1,6 +1,9 @@ # Time: O(n) # Space: O(n) +import collections + + # Hash solution. class Solution(object): def isReflected(self, points): diff --git a/Python/logger-rate-limiter.py b/Python/logger-rate-limiter.py index 0e4006813..7fe8abc07 100644 --- a/Python/logger-rate-limiter.py +++ b/Python/logger-rate-limiter.py @@ -1,6 +1,9 @@ # Time: O(1), amortized # Space: O(k), k is the max number of printed messages in last 10 seconds +import collections + + class Logger(object): def __init__(self): diff --git a/Python/lonely-pixel-ii.py b/Python/lonely-pixel-ii.py index 25bb4c408..e4046be81 100644 --- a/Python/lonely-pixel-ii.py +++ b/Python/lonely-pixel-ii.py @@ -1,6 +1,9 @@ # Time: O(m * n) # Space: O(m * n) +import collections + + class Solution(object): def findBlackPixel(self, picture, N): """ diff --git a/Python/longest-harmonious-subsequence.py b/Python/longest-harmonious-subsequence.py index 585179747..7f394cf97 100644 --- a/Python/longest-harmonious-subsequence.py +++ b/Python/longest-harmonious-subsequence.py @@ -1,10 +1,10 @@ # Time: O(n) # Space: O(n) -# We define a harmonious array is an array where the difference +# We define a harmonious array is an array where the difference # between its maximum value and its minimum value is exactly 1. # -# Now, given an integer array, you need to find the length of its +# Now, given an integer array, you need to find the length of its # longest harmonious subsequence among all its possible subsequences. # # Example 1: @@ -13,6 +13,9 @@ # Explanation: The longest harmonious subsequence is [3,2,2,2,3]. # Note: The length of the input array will not exceed 20,000. +import collections + + class Solution(object): def findLHS(self, nums): """ diff --git a/Python/longest-word-in-dictionary.py b/Python/longest-word-in-dictionary.py index b6f900c14..c437f244a 100644 --- a/Python/longest-word-in-dictionary.py +++ b/Python/longest-word-in-dictionary.py @@ -7,17 +7,17 @@ # # If there is no answer, return the empty string. # Example 1: -# Input: +# Input: # words = ["w","wo","wor","worl", "world"] # Output: "world" -# Explanation: +# Explanation: # The word "world" can be built one character at a time by "w", "wo", "wor", and "worl". # # Example 2: -# Input: +# Input: # words = ["a", "banana", "app", "appl", "ap", "apply", "apple"] # Output: "apple" -# Explanation: +# Explanation: # Both "apply" and "apple" can be built from other words in the dictionary. # However, "apple" is lexicographically smaller than "apply". # @@ -26,6 +26,9 @@ # - The length of words will be in the range [1, 1000]. # - The length of words[i] will be in the range [1, 30]. +import collections + + class Solution(object): def longestWord(self, words): """ diff --git a/Python/magical-string.py b/Python/magical-string.py index 299d6b842..4954f9c1d 100644 --- a/Python/magical-string.py +++ b/Python/magical-string.py @@ -28,6 +28,10 @@ # Explanation: The first 6 elements of magical string S is "12211" and it contains three 1's, so return 3. # the solution comes from https://discuss.leetcode.com/topic/75242/o-log-n-space-using-recursive-generators + +import itertools + + class Solution(object): def magicalString(self, n): """ diff --git a/Python/map-sum-pairs.py b/Python/map-sum-pairs.py index 391bff1c1..1bc72f6cc 100644 --- a/Python/map-sum-pairs.py +++ b/Python/map-sum-pairs.py @@ -16,6 +16,9 @@ # Input: insert("app", 2), Output: Null # Input: sum("ap"), Output: 5 +import collections + + class MapSum(object): def __init__(self): @@ -25,7 +28,7 @@ def __init__(self): _trie = lambda: collections.defaultdict(_trie) self.__root = _trie() - + def insert(self, key, val): """ :type key: str @@ -39,7 +42,7 @@ def insert(self, key, val): delta = val if "_end" in curr: delta -= curr["_end"] - + curr = self.__root for c in key: curr = curr[c] diff --git a/Python/max-increase-to-keep-city-skyline.py b/Python/max-increase-to-keep-city-skyline.py index ce46816ad..902b54825 100644 --- a/Python/max-increase-to-keep-city-skyline.py +++ b/Python/max-increase-to-keep-city-skyline.py @@ -4,7 +4,7 @@ # In a 2 dimensional array grid, each value grid[i][j] represents the height of # a building located there. We are allowed to increase the height of any number of buildings, # by any amount (the amounts can be different for different buildings). -# Height 0 is considered to be a building as well. +# Height 0 is considered to be a building as well. # # At the end, the "skyline" when viewed from all four directions of the grid, # i.e. top, bottom, left, and right, must be the same as the skyline of the original grid. @@ -16,9 +16,9 @@ # Example: # Input: grid = [[3,0,8,4],[2,4,5,7],[9,2,6,3],[0,3,1,0]] # Output: 35 -# Explanation: +# Explanation: # The grid is: -# [ [3, 0, 8, 4], +# [ [3, 0, 8, 4], # [2, 4, 5, 7], # [9, 2, 6, 3], # [0, 3, 1, 0] ] @@ -38,7 +38,10 @@ # - All heights grid[i][j] are in the range [0, 100]. # - All buildings in grid[i][j] occupy the entire grid cell: # that is, they are a 1 x 1 x grid[i][j] rectangular prism. - + +import itertools + + class Solution(object): def maxIncreaseKeepingSkyline(self, grid): """ diff --git a/Python/max-points-on-a-line.py b/Python/max-points-on-a-line.py index 67b31f245..79467c9a3 100644 --- a/Python/max-points-on-a-line.py +++ b/Python/max-points-on-a-line.py @@ -4,6 +4,9 @@ # Given n points on a 2D plane, find the maximum number of points that lie on the same straight line. # +import collections + + # Definition for a point class Point: def __init__(self, a=0, b=0): @@ -28,13 +31,13 @@ def maxPoints(self, points): if start.x - end.x != 0: slope = (start.y - end.y) * 1.0 / (start.x - end.x) slope_count[slope] += 1 - - current_max = same + + current_max = same for slope in slope_count: current_max = max(current_max, slope_count[slope] + same) - + max_points = max(max_points, current_max) - + return max_points if __name__ == "__main__": diff --git a/Python/max-stack.py b/Python/max-stack.py index ee10bd1d8..7bf4ec185 100644 --- a/Python/max-stack.py +++ b/Python/max-stack.py @@ -4,7 +4,10 @@ # top: O(1) # peekMax: O(1) # Space: O(n), n is the number of values in the current stack - + +import collections + + class MaxStack(object): def __init__(self): @@ -15,7 +18,7 @@ def __init__(self): self.__val_to_idxs = collections.defaultdict(list) self.__top = None self.__max = None - + def push(self, x): """ @@ -36,7 +39,7 @@ def pop(self): val = self.__top self.__remove(val) return val - + def top(self): """ @@ -44,14 +47,14 @@ def top(self): """ return self.__top - + def peekMax(self): """ :rtype: int """ return self.__max - + def popMax(self): """ :rtype: int @@ -59,8 +62,8 @@ def popMax(self): val = self.__max self.__remove(val) return val - - + + def __remove(self, val): idx = self.__val_to_idxs[val][-1] self.__val_to_idxs[val].pop(); @@ -71,7 +74,7 @@ def __remove(self, val): self.__top = self.__idx_to_val[max(self.__idx_to_val.keys())] if self.__idx_to_val else None if val == self.__max: self.__max = max(self.__val_to_idxs.keys()) if self.__val_to_idxs else None - + # Your MaxStack object will be instantiated and called as such: # obj = MaxStack() diff --git a/Python/maximum-length-of-repeated-subarray.py b/Python/maximum-length-of-repeated-subarray.py index be588aa9c..e633ed608 100644 --- a/Python/maximum-length-of-repeated-subarray.py +++ b/Python/maximum-length-of-repeated-subarray.py @@ -9,13 +9,17 @@ # A: [1,2,3,2,1] # B: [3,2,1,4,7] # Output: 3 -# Explanation: +# Explanation: # The repeated subarray with maximum length is [3, 2, 1]. # Note: # 1 <= len(A), len(B) <= 1000 # 0 <= A[i], B[i] < 100 # dp solution (3752 ms) + +import collections + + class Solution(object): def findLength(self, A, B): """ @@ -35,9 +39,9 @@ def findLength(self, A, B): result = max(result, max(dp[(i+1)%2])) return result - + # Time: O(m * n * log(min(m, n))) -# Space: O(min(m, n)) +# Space: O(min(m, n)) # Binary search + rolling hash solution (226 ms) class Solution2(object): def findLength(self, A, B): @@ -93,7 +97,7 @@ def findLength(self, A, B): :rtype: int """ if len(A) > len(B): return findLength(B, A) - + def check(length): lookup = set(A[i:i+length] \ for i in xrange(len(A)-length+1)) diff --git a/Python/minesweeper.py b/Python/minesweeper.py index a3a9fe712..e5ee0b93d 100644 --- a/Python/minesweeper.py +++ b/Python/minesweeper.py @@ -14,32 +14,32 @@ # If a mine ('M') is revealed, then the game is over - change it to 'X'. # If an empty square ('E') with no adjacent mines is revealed, then change it to revealed blank ('B') # and all of its adjacent unrevealed squares should be revealed recursively. -# If an empty square ('E') with at least one adjacent mine is revealed, then change it to a digit ('1' to '8') +# If an empty square ('E') with at least one adjacent mine is revealed, then change it to a digit ('1' to '8') # representing the number of adjacent mines. # Return the board when no more squares will be revealed. # # Example 1: -# Input: +# Input: # [['E', 'E', 'E', 'E', 'E'], # ['E', 'E', 'M', 'E', 'E'], # ['E', 'E', 'E', 'E', 'E'], # ['E', 'E', 'E', 'E', 'E']] # Click : [3,0] -# Output: +# Output: # [['B', '1', 'E', '1', 'B'], # ['B', '1', 'M', '1', 'B'], # ['B', '1', '1', '1', 'B'], # ['B', 'B', 'B', 'B', 'B']] # # Example 2: -# Input: +# Input: # [['B', '1', 'E', '1', 'B'], # ['B', '1', 'M', '1', 'B'], # ['B', '1', '1', '1', 'B'], # ['B', 'B', 'B', 'B', 'B']] # # Click : [1,2] -# Output: +# Output: # [['B', '1', 'E', '1', 'B'], # ['B', '1', 'X', '1', 'B'], # ['B', '1', '1', '1', 'B'], @@ -50,10 +50,13 @@ # The click position will only be an unrevealed square ('M' or 'E'), # which also means the input board contains at least one clickable square. # The input board won't be a stage when game is over (some mines have been revealed). -# For simplicity, not mentioned rules should be ignored in this problem. +# For simplicity, not mentioned rules should be ignored in this problem. # For example, you don't need to reveal all the unrevealed mines when the game is over, # consider any cases that you will win the game or flag any squares. +import collections + + class Solution(object): def updateBoard(self, board, click): """ @@ -77,7 +80,7 @@ def updateBoard(self, board, click): continue if board[r][c] == 'M' or board[r][c] == 'X': count += 1 - + if count: board[row][col] = chr(count + ord('0')) else: @@ -119,7 +122,7 @@ def updateBoard(self, board, click): continue if board[r][c] == 'M' or board[r][c] == 'X': count += 1 - + if count: board[row][col] = chr(count + ord('0')) else: @@ -135,4 +138,3 @@ def updateBoard(self, board, click): self.updateBoard(board, (r, c)) return board - diff --git a/Python/minimum-height-trees.py b/Python/minimum-height-trees.py index dbd7df905..41ba4bc8c 100644 --- a/Python/minimum-height-trees.py +++ b/Python/minimum-height-trees.py @@ -5,7 +5,7 @@ # choose any node as the root. The result graph is then a # rooted tree. Among all possible rooted trees, those with # minimum height are called minimum height trees (MHTs). -# Given such a graph, write a function to find all the +# Given such a graph, write a function to find all the # MHTs and return a list of their root labels. # # Format @@ -46,14 +46,17 @@ # How many MHTs can a graph have at most? # Note: # -# (1) According to the definition of tree on Wikipedia: -# "a tree is an undirected graph in which any two vertices -# are connected by exactly one path. In other words, +# (1) According to the definition of tree on Wikipedia: +# "a tree is an undirected graph in which any two vertices +# are connected by exactly one path. In other words, # any connected graph without simple cycles is a tree." # -# (2) The height of a rooted tree is the number of edges on the +# (2) The height of a rooted tree is the number of edges on the # longest downward path between the root and a leaf. +import collections + + class Solution(object): def findMinHeightTrees(self, n, edges): """ @@ -76,17 +79,17 @@ def findMinHeightTrees(self, n, edges): unvisited.add(i) # A graph can have 2 MHTs at most. - # BFS from the leaves until the number + # BFS from the leaves until the number # of the unvisited nodes is less than 3. while len(unvisited) > 2: cur_level = [] for u in pre_level: unvisited.remove(u) for v in neighbors[u]: - if v in unvisited: + if v in unvisited: neighbors[v].remove(u) if len(neighbors[v]) == 1: cur_level.append(v) pre_level = cur_level - + return list(unvisited) diff --git a/Python/missing-number.py b/Python/missing-number.py index 39aae053a..b2b3426f0 100644 --- a/Python/missing-number.py +++ b/Python/missing-number.py @@ -8,10 +8,13 @@ # Given nums = [0, 1, 3] return 2. # # Note: -# Your algorithm should run in linear runtime complexity. +# Your algorithm should run in linear runtime complexity. # Could you implement it using only constant extra space complexity? # +import operator + + class Solution(object): def missingNumber(self, nums): """ diff --git a/Python/most-frequent-subtree-sum.py b/Python/most-frequent-subtree-sum.py index ca261a1b5..202eb6baa 100644 --- a/Python/most-frequent-subtree-sum.py +++ b/Python/most-frequent-subtree-sum.py @@ -30,6 +30,9 @@ # self.left = None # self.right = None +import collections + + class Solution(object): def findFrequentTreeSum(self, root): """ diff --git a/Python/my-calendar-iii.py b/Python/my-calendar-iii.py index 985a001a6..eacc90de9 100644 --- a/Python/my-calendar-iii.py +++ b/Python/my-calendar-iii.py @@ -23,7 +23,7 @@ # MyCalendarThree.book(5, 15); // returns 3 # MyCalendarThree.book(5, 10); // returns 3 # MyCalendarThree.book(25, 55); // returns 3 -# Explanation: +# Explanation: # The first two events can be booked and are disjoint, so the maximum K-booking is a 1-booking. # The third event [10, 40) intersects the first event, and the maximum K-booking is a 2-booking. # The remaining events cause the maximum K-booking to be only a 3-booking. @@ -32,12 +32,15 @@ # Note: # - The number of calls to MyCalendarThree.book per test case will be at most 400. # - In calls to MyCalendarThree.book(start, end), start and end are integers in the range [0, 10^9]. - + +import bisect + + class MyCalendarThree(object): def __init__(self): self.__books = [] - + def book(self, start, end): """ @@ -50,19 +53,19 @@ def book(self, start, end): self.__books[i] = (self.__books[i][0], self.__books[i][1]+1) else: self.__books.insert(i, (start, 1)) - + j = bisect.bisect_left(self.__books, (end, 1)) if j < len(self.__books) and self.__books[j][0] == end: self.__books[j] = (self.__books[j][0], self.__books[j][1]-1) else: self.__books.insert(j, (end, -1)) - + result, cnt = 0, 0 for book in self.__books: cnt += book[1] - result = max(result, cnt) + result = max(result, cnt) return result - + # Your MyCalendarThree object will be instantiated and called as such: # obj = MyCalendarThree() diff --git a/Python/network-delay-time.py b/Python/network-delay-time.py index b8f2a237f..f4251b59a 100644 --- a/Python/network-delay-time.py +++ b/Python/network-delay-time.py @@ -16,6 +16,9 @@ # - The length of times will be in the range [1, 6000]. # - All edges times[i] = (u, v, w) will have 1 <= u, v <= N and 1 <= w <= 100. +import heapq + + # Dijkstra's algorithm class Solution(object): def networkDelayTime(self, times, N, K): @@ -28,7 +31,7 @@ def networkDelayTime(self, times, N, K): adj = [[] for _ in xrange(N)] for u, v, w in times: adj[u-1].append((v-1, w)) - + result = 0 lookup = set() min_heap = [(0, K-1)] @@ -39,4 +42,3 @@ def networkDelayTime(self, times, N, K): if v in lookup: continue heapq.heappush(min_heap, (result+w, v)) return result if len(lookup) == N else -1 - diff --git a/Python/next-greater-element-iii.py b/Python/next-greater-element-iii.py index 9a4f344ea..2f0752522 100644 --- a/Python/next-greater-element-iii.py +++ b/Python/next-greater-element-iii.py @@ -4,7 +4,7 @@ # Given a positive 32-bit integer n, you need to find the smallest 32-bit integer # which has exactly the same digits existing in the integer n and is greater in value than n. # If no such positive 32-bit integer exists, you need to return -1. -@ +# # Example 1: # Input: 12 # Output: 21 @@ -12,6 +12,12 @@ # Input: 21 # Output: -1 +try: + xrange # Python 2 +except NameError: + xrange = range # Python 3 + + class Solution(object): def nextGreaterElement(self, n): """ @@ -23,15 +29,15 @@ def nextGreaterElement(self, n): for i in xrange(len(digits) - 1): if digits[i] < digits[i + 1]: k = i - + if k == -1: digits.reverse() return -1 - + for i in xrange(k + 1, len(digits)): if digits[i] > digits[k]: l = i - + digits[k], digits[l] = digits[l], digits[k] digits[k + 1:] = digits[:k:-1] result = int("".join(map(str, digits))) diff --git a/Python/number-of-atoms.py b/Python/number-of-atoms.py index ca0bb7fab..ac37e2251 100644 --- a/Python/number-of-atoms.py +++ b/Python/number-of-atoms.py @@ -20,24 +20,24 @@ # followed by its count (if that count is more than 1), and so on. # # Example 1: -# Input: +# Input: # formula = "H2O" # Output: "H2O" -# Explanation: +# Explanation: # The count of elements are {'H': 2, 'O': 1}. # # Example 2: -# Input: +# Input: # formula = "Mg(OH)2" # Output: "H2MgO2" -# Explanation: +# Explanation: # The count of elements are {'H': 2, 'Mg': 1, 'O': 2}. # # Example 3: -# Input: +# Input: # formula = "K4(ON(SO3)2)2" # Output: "K4N2O14S4" -# Explanation: +# Explanation: # The count of elements are {'K': 4, 'N': 2, 'O': 14, 'S': 4}. # Note: # @@ -46,6 +46,10 @@ # formula will only consist of letters, digits, and round parentheses, # and is a valid formula as defined in the problem. +import collections +import re + + class Solution(object): def countOfAtoms(self, formula): """ diff --git a/Python/number-of-matching-subsequences.py b/Python/number-of-matching-subsequences.py index 86b8af903..f6d3602a2 100644 --- a/Python/number-of-matching-subsequences.py +++ b/Python/number-of-matching-subsequences.py @@ -4,7 +4,7 @@ # Given string S and a dictionary of words words, find the number of words[i] that is a subsequence of S. # # Example : -# Input: +# Input: # S = "abcde" # words = ["a", "bb", "acd", "ace"] # Output: 3 @@ -16,6 +16,9 @@ # - The length of words will be in the range of [1, 5000]. # - The length of words[i] will be in the range of [1, 50]. +import collections + + class Solution(object): def numMatchingSubseq(self, S, words): """ diff --git a/Python/optimal-account-balancing.py b/Python/optimal-account-balancing.py index 4d409c853..32ffe34e4 100644 --- a/Python/optimal-account-balancing.py +++ b/Python/optimal-account-balancing.py @@ -1,6 +1,9 @@ # Time: O(n * 2^n), n is the size of the debt. # Space: O(n * 2^n) +import collections + + class Solution(object): def minTransfers(self, transactions): """ @@ -16,7 +19,7 @@ def minTransfers(self, transactions): for v in account.values(): if v: debt.append(v) - + if not debt: return 0 diff --git a/Python/palindrome-pairs.py b/Python/palindrome-pairs.py index bf823ce55..eb9283bae 100644 --- a/Python/palindrome-pairs.py +++ b/Python/palindrome-pairs.py @@ -2,7 +2,7 @@ # Space: O(n * k) # Given a list of unique words. Find all pairs of indices (i, j) -# in the given list, so that the concatenation of the two words, +# in the given list, so that the concatenation of the two words, # i.e. words[i] + words[j] is a palindrome. # # Example 1: @@ -14,13 +14,16 @@ # Return [[0, 1], [1, 0], [3, 2], [2, 4]] # The palindromes are ["dcbaabcd", "abcddcba", "slls", "llssssll"] +import collections + + class Solution(object): def palindromePairs(self, words): """ :type words: List[str] :rtype: List[List[int]] """ - res = [] + res = [] lookup = {} for i, word in enumerate(words): lookup[word] = i @@ -55,7 +58,7 @@ def preProcess(s): T += ["#", c] T += ['#', '$'] return T - + T = preProcess(s) center, right = 0, 0 for i in xrange(1, len(T) - 1): diff --git a/Python/palindrome-permutation-ii.py b/Python/palindrome-permutation-ii.py index 097f0956a..c74444ba0 100644 --- a/Python/palindrome-permutation-ii.py +++ b/Python/palindrome-permutation-ii.py @@ -1,6 +1,10 @@ # Time: O(n * n!) # Space: O(n) +import collections +import itertools + + class Solution(object): def generatePalindromes(self, s): """ @@ -11,13 +15,13 @@ def generatePalindromes(self, s): mid = ''.join(k for k, v in cnt.iteritems() if v % 2) chars = ''.join(k * (v / 2) for k, v in cnt.iteritems()) return self.permuteUnique(mid, chars) if len(mid) < 2 else [] - + def permuteUnique(self, mid, nums): result = [] used = [False] * len(nums) self.permuteUniqueRecu(mid, result, used, [], nums) return result - + def permuteUniqueRecu(self, mid, result, used, cur, nums): if len(cur) == len(nums): half_palindrome = ''.join(cur) diff --git a/Python/palindrome-permutation.py b/Python/palindrome-permutation.py index 21df60552..1932a00ee 100644 --- a/Python/palindrome-permutation.py +++ b/Python/palindrome-permutation.py @@ -1,10 +1,13 @@ # Time: O(n) # Space: O(1) +import collections + + class Solution(object): def canPermutePalindrome(self, s): """ :type s: str :rtype: bool """ - return sum(v % 2 for v in collections.Counter(s).values()) < 2 + return sum(v % 2 for v in collections.Counter(s).values()) < 2 diff --git a/Python/path-sum-iii.py b/Python/path-sum-iii.py index ed24dde54..a3b8f6cc2 100644 --- a/Python/path-sum-iii.py +++ b/Python/path-sum-iii.py @@ -5,7 +5,7 @@ # # Find the number of paths that sum to a given value. # -# The path does not need to start or end at the root or a leaf, +# The path does not need to start or end at the root or a leaf, # but it must go downwards (traveling only from parent nodes to child nodes). # # The tree has no more than 1,000 nodes and the values are in the range -1,000,000 to 1,000,000. @@ -35,6 +35,9 @@ # self.left = None # self.right = None +import collections + + class Solution(object): def pathSum(self, root, sum): """ @@ -54,7 +57,7 @@ def pathSumHelper(root, curr, sum, lookup): if lookup[curr] == 0: del lookup[curr] return result - + lookup = collections.defaultdict(int) lookup[0] = 1 return pathSumHelper(root, 0, sum, lookup) diff --git a/Python/path-sum-iv.py b/Python/path-sum-iv.py index ead4b0735..6ee097bfa 100644 --- a/Python/path-sum-iv.py +++ b/Python/path-sum-iv.py @@ -1,6 +1,9 @@ # Time: O(n) # Space: O(p), p is the number of paths +import collections + + class Solution(object): def pathSum(self, nums): """ @@ -13,7 +16,7 @@ def __init__(self, num): self.i = (num%100)/10 - 1 self.val = num%10 self.leaf = True - + def isParent(self, other): return self.level == other.level-1 and \ self.i == other.i/2 diff --git a/Python/permutation-in-string.py b/Python/permutation-in-string.py index 171502725..338244159 100644 --- a/Python/permutation-in-string.py +++ b/Python/permutation-in-string.py @@ -16,6 +16,9 @@ # The input strings only contain lower case letters. # The length of both given strings is in range [1, 10,000]. +import collections + + class Solution(object): def checkInclusion(self, s1, s2): """ diff --git a/Python/poor-pigs.py b/Python/poor-pigs.py index c5263a9d3..5c33be03a 100644 --- a/Python/poor-pigs.py +++ b/Python/poor-pigs.py @@ -15,6 +15,9 @@ # how many pigs (x) you need to figure out the "poison" bucket within p minutes? # There is exact one bucket with poison. +import math + + class Solution(object): def poorPigs(self, buckets, minutesToDie, minutesToTest): """ diff --git a/Python/prefix-and-suffix-search.py b/Python/prefix-and-suffix-search.py index caecf336c..8c2eb8b23 100644 --- a/Python/prefix-and-suffix-search.py +++ b/Python/prefix-and-suffix-search.py @@ -21,12 +21,15 @@ # prefix, suffix have lengths in range [0, 10]. # words[i] and prefix, suffix queries consist of lowercase letters only. +import collections + + class WordFilter(object): def __init__(self, words): """ :type words: List[str] - """ + """ _trie = lambda: collections.defaultdict(_trie) self.__trie = _trie() @@ -38,7 +41,7 @@ def __init__(self, words): for j in xrange(i, 2*len(word)-1): cur = cur[word[j%len(word)]] cur["_weight"] = weight - + def f(self, prefix, suffix): """ :type prefix: str @@ -58,7 +61,7 @@ def f(self, prefix, suffix): # m is the number of the prefix match, n is the number of the suffix match # Space: O(w * l) class Trie(object): - + def __init__(self): _trie = lambda: collections.defaultdict(_trie) self.__trie = _trie() @@ -89,7 +92,7 @@ class WordFilter2(object): def __init__(self, words): """ :type words: List[str] - """ + """ self.__prefix_trie = Trie() self.__suffix_trie = Trie() for i in reversed(xrange(len(words))): @@ -101,7 +104,7 @@ def f(self, prefix, suffix): :type prefix: str :type suffix: str :rtype: int - """ + """ prefix_match = self.__prefix_trie.find(prefix) suffix_match = self.__suffix_trie.find(suffix[::-1]) i, j = 0, 0 @@ -113,8 +116,8 @@ def f(self, prefix, suffix): else: j += 1 return -1 - - + + # Your WordFilter object will be instantiated and called as such: # obj = WordFilter(words) # param_1 = obj.f(prefix,suffix) diff --git a/Python/rabbits-in-forest.py b/Python/rabbits-in-forest.py index 0c3dad1d6..bd92a73b9 100644 --- a/Python/rabbits-in-forest.py +++ b/Python/rabbits-in-forest.py @@ -27,6 +27,9 @@ # - answers will have length at most 1000. # - Each answers[i] will be an integer in the range [0, 999]. +import collections + + class Solution(object): def numRabbits(self, answers): """ diff --git a/Python/range-module.py b/Python/range-module.py index 612011f0e..f5a2adbb0 100644 --- a/Python/range-module.py +++ b/Python/range-module.py @@ -27,7 +27,10 @@ # - The total number of calls to addRange in a single test case is at most 1000. # - The total number of calls to queryRange in a single test case is at most 5000. # - The total number of calls to removeRange in a single test case is at most 1000. - + +import bisect + + class RangeModule(object): def __init__(self): diff --git a/Python/reach-a-number.py b/Python/reach-a-number.py index 138054d34..ff4344ee7 100644 --- a/Python/reach-a-number.py +++ b/Python/reach-a-number.py @@ -26,6 +26,9 @@ # Note: # - target will be a non-zero integer in the range [-10^9, 10^9]. +import math + + class Solution(object): def reachNumber(self, target): """ @@ -36,7 +39,7 @@ def reachNumber(self, target): k = int(math.ceil((-1+math.sqrt(1+8*target))/2)) target -= k*(k+1)/2 return k if target%2 == 0 else k+1+k%2 - + # Time: O(sqrt(n)) # Space: O(1) @@ -52,4 +55,3 @@ def reachNumber(self, target): k += 1 target -= k return k if target%2 == 0 else k+1+k%2 - diff --git a/Python/reconstruct-itinerary.py b/Python/reconstruct-itinerary.py index 2305889b4..b1864972f 100644 --- a/Python/reconstruct-itinerary.py +++ b/Python/reconstruct-itinerary.py @@ -1,4 +1,4 @@ -# Time: O(t! / (n1! * n2! * ... nk!)), t is the total number of tickets, +# Time: O(t! / (n1! * n2! * ... nk!)), t is the total number of tickets, # ni is the number of the ticket which from is city i, # k is the total number of cities. # Space: O(t) @@ -10,7 +10,7 @@ # # Note: # If there are multiple valid itineraries, you should return the itinerary -# that has the smallest lexical order when read as a single string. +# that has the smallest lexical order when read as a single string. # For example, the itinerary ["JFK", "LGA"] has a smaller lexical # order than ["JFK", "LGB"]. # All airports are represented by three capital letters (IATA code). @@ -24,6 +24,9 @@ # Another possible reconstruction is ["JFK","SFO","ATL","JFK","ATL","SFO"]. # But it is larger in lexical order. +import collections + + class Solution(object): def findItinerary(self, tickets): """ diff --git a/Python/remove-duplicate-letters.py b/Python/remove-duplicate-letters.py index 552643870..665537749 100644 --- a/Python/remove-duplicate-letters.py +++ b/Python/remove-duplicate-letters.py @@ -14,6 +14,9 @@ # Given "cbacdcbc" # Return "acdb" +import collections + + class Solution(object): def removeDuplicateLetters(self, s): """ diff --git a/Python/reorganize-string.py b/Python/reorganize-string.py index aa2dca926..719c1aeac 100644 --- a/Python/reorganize-string.py +++ b/Python/reorganize-string.py @@ -18,6 +18,10 @@ # Note: # - S will consist of lowercase letters and have length in range [1, 500]. +import collections +import heapq + + class Solution(object): def reorganizeString(self, S): """ @@ -27,7 +31,7 @@ def reorganizeString(self, S): counts = collections.Counter(S) if any(v > (len(S)+1)/2 for k, v in counts.iteritems()): return "" - + result = [] max_heap = [] for k, v in counts.iteritems(): diff --git a/Python/replace-words.py b/Python/replace-words.py index 8ed8c2513..662f8ec0f 100644 --- a/Python/replace-words.py +++ b/Python/replace-words.py @@ -22,6 +22,9 @@ # 1 <= root length <= 100 # 1 <= sentence words length <= 1000 +import collections + + class Solution(object): def replaceWords(self, dictionary, sentence): """ diff --git a/Python/second-minimum-node-in-a-binary-tree.py b/Python/second-minimum-node-in-a-binary-tree.py index ac2b21761..e300f12e5 100644 --- a/Python/second-minimum-node-in-a-binary-tree.py +++ b/Python/second-minimum-node-in-a-binary-tree.py @@ -11,7 +11,7 @@ # If no such second minimum value exists, output -1 instead. # # Example 1: -# Input: +# Input: # 2 # / \ # 2 5 @@ -21,14 +21,14 @@ # Output: 5 # Explanation: The smallest value is 2, the second smallest value is 5. # Example 2: -# Input: +# Input: # 2 # / \ # 2 2 # # Output: -1 # Explanation: The smallest value is 2, but there isn't any second smallest value. - + # Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): @@ -36,6 +36,9 @@ # self.left = None # self.right = None +import heapq + + class Solution(object): def findSecondMinimumValue(self, root): """ diff --git a/Python/sentence-similarity-ii.py b/Python/sentence-similarity-ii.py index 3e0d8895a..312e04df2 100644 --- a/Python/sentence-similarity-ii.py +++ b/Python/sentence-similarity-ii.py @@ -29,6 +29,9 @@ # - The length of each pairs[i] will be 2. # - The length of each words[i] and pairs[i][j] will be in the range [1, 20]. +import itertools + + class UnionFind(object): def __init__(self, n): self.set = range(n) diff --git a/Python/sentence-similarity.py b/Python/sentence-similarity.py index 02ee74720..2cad00bba 100644 --- a/Python/sentence-similarity.py +++ b/Python/sentence-similarity.py @@ -27,6 +27,9 @@ # - The length of each pairs[i] will be 2. # - The length of each words[i] and pairs[i][j] will be in the range [1, 20]. +import itertools + + class Solution(object): def areSentencesSimilar(self, words1, words2, pairs): """ diff --git a/Python/sequence-reconstruction.py b/Python/sequence-reconstruction.py index 8b492df2a..5de09aed0 100644 --- a/Python/sequence-reconstruction.py +++ b/Python/sequence-reconstruction.py @@ -1,6 +1,9 @@ # Time: O(n * s), n is the size of org, s is the size of seqs # Space: O(n) +import collections + + class Solution(object): def sequenceReconstruction(self, org, seqs): """ @@ -79,4 +82,3 @@ def sequenceReconstruction(self, org, seqs): return False q.append(j) return res == org and len(org) == len(integer_set) - diff --git a/Python/serialize-and-deserialize-bst.py b/Python/serialize-and-deserialize-bst.py index 811fa44c2..7ab9837df 100644 --- a/Python/serialize-and-deserialize-bst.py +++ b/Python/serialize-and-deserialize-bst.py @@ -23,11 +23,14 @@ # self.left = None # self.right = None +import collections + + class Codec: def serialize(self, root): """Encodes a tree to a single string. - + :type root: TreeNode :rtype: str """ @@ -45,7 +48,7 @@ def serializeHelper(node, vals): def deserialize(self, data): """Decodes your encoded data to tree. - + :type data: str :rtype: TreeNode """ diff --git a/Python/shortest-completing-word.py b/Python/shortest-completing-word.py index 49c50fe11..46890b5c3 100644 --- a/Python/shortest-completing-word.py +++ b/Python/shortest-completing-word.py @@ -32,6 +32,9 @@ # - words will have a length in the range [10, 1000]. # - Every words[i] will consist of lowercase letters, and have length in range [1, 15]. +import collections + + class Solution(object): def shortestCompletingWord(self, licensePlate, words): """ diff --git a/Python/shortest-word-distance-ii.py b/Python/shortest-word-distance-ii.py index fb76a188c..21807b273 100644 --- a/Python/shortest-word-distance-ii.py +++ b/Python/shortest-word-distance-ii.py @@ -1,6 +1,9 @@ # Time: init: O(n), lookup: O(a + b), a, b is occurences of word1, word2 # Space: O(n) +import collections + + class WordDistance: # initialize your data structure here. # @param {string[]} words @@ -26,4 +29,3 @@ def shortest(self, word1, word2): j += 1 return dist - diff --git a/Python/shuffle-an-array.py b/Python/shuffle-an-array.py index 0d373852a..0bafe4e79 100644 --- a/Python/shuffle-an-array.py +++ b/Python/shuffle-an-array.py @@ -19,11 +19,14 @@ # // Returns the random shuffling of array [1,2,3]. # solution.shuffle(); +import random + + class Solution(object): def __init__(self, nums): """ - + :type nums: List[int] :type size: int """ @@ -36,7 +39,7 @@ def reset(self): :rtype: List[int] """ return self.__nums - + def shuffle(self): """ diff --git a/Python/sliding-puzzle.py b/Python/sliding-puzzle.py index 25ba2b692..04d104fed 100644 --- a/Python/sliding-puzzle.py +++ b/Python/sliding-puzzle.py @@ -9,7 +9,7 @@ # The state of the board is solved if and only if the board is [[1,2,3],[4,5,0]]. # # Given a puzzle board, return the least number of moves required -# so that the state of the board is solved. If it is impossible +# so that the state of the board is solved. If it is impossible # for the state of the board to be solved, return -1. # # Examples: @@ -37,6 +37,10 @@ # - board will be a 2 x 3 array as described above. # - board[i][j] will be a permutation of [0, 1, 2, 3, 4, 5]. +import heapq +import itertools + + # A* Search Algorithm class Solution(object): def slidingPuzzle(self, board): @@ -46,7 +50,7 @@ def slidingPuzzle(self, board): """ def dot(p1, p2): return p1[0]*p2[0]+p1[1]*p2[1] - + def heuristic_estimate(board, R, C, expected): result = 0 for i in xrange(R): @@ -56,13 +60,13 @@ def heuristic_estimate(board, R, C, expected): r, c = expected[val] result += abs(r-i) + abs(c-j) return result - + R, C = len(board), len(board[0]) begin = tuple(itertools.chain(*board)) end = tuple(range(1, R*C) + [0]) expected = {(C*i+j+1) % (R*C) : (i, j) for i in xrange(R) for j in xrange(C)} - + min_steps = heuristic_estimate(begin, R, C, expected) closer, detour = [(begin.index(0), begin)], [] lookup = set() @@ -111,14 +115,14 @@ def heuristic_estimate(board, R, C, expected): r, c = expected[val] result += abs(r-i) + abs(c-j) return result - + R, C = len(board), len(board[0]) begin = tuple(itertools.chain(*board)) end = tuple(range(1, R*C) + [0]) end_wrong = tuple(range(1, R*C-2) + [R*C-1, R*C-2, 0]) expected = {(C*i+j+1) % (R*C) : (i, j) for i in xrange(R) for j in xrange(C)} - + min_heap = [(0, 0, begin.index(0), begin)] lookup = {begin: 0} while min_heap: diff --git a/Python/smallest-good-base.py b/Python/smallest-good-base.py index c63d418b6..ca093562b 100644 --- a/Python/smallest-good-base.py +++ b/Python/smallest-good-base.py @@ -3,7 +3,7 @@ # For an integer n, we call k>=2 a good base of n, if all digits of n base k are 1. # -# Now given a string representing n, you should return the smallest good base of n in string format. +# Now given a string representing n, you should return the smallest good base of n in string format. # # Example 1: # Input: "13" @@ -21,6 +21,9 @@ # The range of n is [3, 10^18]. # The string representing n is always valid and will not have leading zeros. +import math + + class Solution(object): def smallestGoodBase(self, n): """ diff --git a/Python/smallest-range.py b/Python/smallest-range.py index 280dd05cf..8b5e76c90 100644 --- a/Python/smallest-range.py +++ b/Python/smallest-range.py @@ -9,7 +9,7 @@ # Example 1: # Input:[[4,10,15,24,26], [0,9,12,20], [5,18,22,30]] # Output: [20,24] -# Explanation: +# Explanation: # List 1: [4, 10, 15, 24,26], 24 is in range [20,24]. # List 2: [0, 9, 12, 20], 20 is in range [20,24]. # List 3: [5, 18, 22, 30], 22 is in range [20,24]. @@ -20,6 +20,9 @@ # For Java users, please note that the input type has been changed to List>. # And after you reset the code template, you'll see this point. +import heapq + + class Solution(object): def smallestRange(self, nums): """ @@ -33,10 +36,10 @@ def smallestRange(self, nums): right = max(right, row[0]) it = iter(row) heapq.heappush(min_heap, (next(it, None), it)) - + result = (left, right) while min_heap: - (val, it) = heapq.heappop(min_heap) + (val, it) = heapq.heappop(min_heap) val = next(it, None) if val is None: break diff --git a/Python/smallest-rectangle-enclosing-black-pixels.py b/Python/smallest-rectangle-enclosing-black-pixels.py index a410c374f..5e54d555d 100644 --- a/Python/smallest-rectangle-enclosing-black-pixels.py +++ b/Python/smallest-rectangle-enclosing-black-pixels.py @@ -1,6 +1,10 @@ # Time: O(nlogn) # Space: O(1) +import bisect +import itertools + + class Solution(object): def minArea(self, image, x, y): """ diff --git a/Python/solve-the-equation.py b/Python/solve-the-equation.py index a5ccdb1bb..21ce493de 100644 --- a/Python/solve-the-equation.py +++ b/Python/solve-the-equation.py @@ -26,6 +26,9 @@ # Input: "x=x+2" # Output: "No solution" +import re + + class Solution(object): def solveEquation(self, equation): """ diff --git a/Python/sort-characters-by-frequency.py b/Python/sort-characters-by-frequency.py index 72712cf14..3bfbde6d7 100644 --- a/Python/sort-characters-by-frequency.py +++ b/Python/sort-characters-by-frequency.py @@ -33,6 +33,9 @@ # "bbaA" is also a valid answer, but "Aabb" is incorrect. # Note that 'A' and 'a' are treated as two different characters. +import collections + + class Solution(object): def frequencySort(self, s): """ @@ -42,14 +45,14 @@ def frequencySort(self, s): freq = collections.defaultdict(int) for c in s: freq[c] += 1 - + counts = [""] * (len(s)+1) for c in freq: counts[freq[c]] += c - + result = "" for count in reversed(xrange(len(counts)-1)): for c in counts[count]: result += c * count - + return result diff --git a/Python/stickers-to-spell-word.py b/Python/stickers-to-spell-word.py index 6309f76ef..180f9889b 100644 --- a/Python/stickers-to-spell-word.py +++ b/Python/stickers-to-spell-word.py @@ -44,6 +44,9 @@ # - The time limit may be more challenging than usual. # It is expected that a 50 sticker test case can be solved within 35ms on average. +import collections + + class Solution(object): def minStickers(self, stickers, target): """ @@ -65,12 +68,11 @@ def minStickersHelper(sticker_counts, target, dp): new_target += [k]*(target_count[k] - sticker_count[k]) if len(new_target) != len(target): num = minStickersHelper(sticker_counts, new_target, dp) - if num != -1: - result = min(result, 1+num) + if num != -1: + result = min(result, 1+num) dp["".join(target)] = -1 if result == float("inf") else result return dp["".join(target)] - + sticker_counts = map(collections.Counter, stickers) dp = { "":0 } return minStickersHelper(sticker_counts, target, dp) - diff --git a/Python/subarray-sum-equals-k.py b/Python/subarray-sum-equals-k.py index 98e7d8ae0..96a14da77 100644 --- a/Python/subarray-sum-equals-k.py +++ b/Python/subarray-sum-equals-k.py @@ -12,6 +12,9 @@ # The length of the array is in range [1, 20,000]. # The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7]. +import collections + + class Solution(object): def subarraySum(self, nums, k): """ diff --git a/Python/substring-with-concatenation-of-all-words.py b/Python/substring-with-concatenation-of-all-words.py index f1127a886..f56813378 100644 --- a/Python/substring-with-concatenation-of-all-words.py +++ b/Python/substring-with-concatenation-of-all-words.py @@ -14,6 +14,10 @@ # (order does not matter). # Sliding window solution + +import collections + + class Solution(object): def findSubstring(self, s, words): """ @@ -24,7 +28,7 @@ def findSubstring(self, s, words): result, m, n, k = [], len(s), len(words), len(words[0]) if m < n*k: return result - + lookup = collections.defaultdict(int) for i in words: lookup[i] += 1 # Space: O(n * k) @@ -36,7 +40,7 @@ def findSubstring(self, s, words): s1 = s[j:j+k]; # Time: O(k) if s1 in lookup: tmp[s1] += 1 - if tmp[s1] <= lookup[s1]: + if tmp[s1] <= lookup[s1]: count += 1 else: while tmp[s1] > lookup[s1]: @@ -69,7 +73,7 @@ def findSubstring(self, s, words): result, m, n, k = [], len(s), len(words), len(words[0]) if m < n*k: return result - + lookup = collections.defaultdict(int) for i in words: lookup[i] += 1 # Space: O(n * k) @@ -78,7 +82,7 @@ def findSubstring(self, s, words): cur, j = collections.defaultdict(int), 0 while j < n: # Time: O(n) word = s[i+j*k:i+j*k+k] # Time: O(k) - if word not in lookup: + if word not in lookup: break cur[word] += 1 if cur[word] > lookup[word]: @@ -86,7 +90,7 @@ def findSubstring(self, s, words): j += 1 if j == n: result.append(i) - + return result diff --git a/Python/sum-of-square-numbers.py b/Python/sum-of-square-numbers.py index bf1a22f24..2688be8d1 100644 --- a/Python/sum-of-square-numbers.py +++ b/Python/sum-of-square-numbers.py @@ -11,7 +11,10 @@ # Example 2: # Input: 3 # Output: False - + +import math + + class Solution(object): def judgeSquareSum(self, c): """ diff --git a/Python/summary-ranges.py b/Python/summary-ranges.py index f602a5282..6bdddb9f2 100644 --- a/Python/summary-ranges.py +++ b/Python/summary-ranges.py @@ -8,6 +8,12 @@ # return ["0->2","4->5","7"]. # +import bisect +import collections +import itertools +import re + + class Solution: # @param {integer[]} nums # @return {string[]} diff --git a/Python/super-ugly-number.py b/Python/super-ugly-number.py index 3775efbb3..4ac12281d 100644 --- a/Python/super-ugly-number.py +++ b/Python/super-ugly-number.py @@ -3,10 +3,10 @@ # Write a program to find the nth super ugly number. # -# Super ugly numbers are positive numbers whose all +# Super ugly numbers are positive numbers whose all # prime factors are in the given prime list primes of size k. # For example, [1, 2, 4, 7, 8, 13, 14, 16, 19, 26, 28, 32] -# is the sequence of the first 12 super ugly numbers given +# is the sequence of the first 12 super ugly numbers given # primes = [2, 7, 13, 19] of size 4. # # Note: @@ -14,6 +14,9 @@ # (2) The given numbers in primes are in ascending order. # (3) 0 < k <= 100, 0 < n <= 106, 0 < primes[i] < 1000. +import heapq + + # Heap solution. (620ms) class Solution(object): def nthSuperUglyNumber(self, n, primes): @@ -109,7 +112,7 @@ def nthSuperUglyNumber(self, n, primes): if uglies[i] == ugly_by_prime[k]: idx[k] += 1 ugly_by_prime[k] = primes[k] * uglies[idx[k]] - + return uglies[-1] # Time: O(n * logk) ~ O(n * klogk) diff --git a/Python/surrounded-regions.py b/Python/surrounded-regions.py index 98e7a65ad..e586a1acc 100644 --- a/Python/surrounded-regions.py +++ b/Python/surrounded-regions.py @@ -2,22 +2,25 @@ # Space: O(m + n) # # Given a 2D board containing 'X' and 'O', capture all regions surrounded by 'X'. -# +# # A region is captured by flipping all 'O's into 'X's in that surrounded region. -# +# # For example, # X X X X # X O O X # X X O X # X O X X # After running your function, the board should be: -# +# # X X X X # X X X X # X X X X # X O X X # +import collections + + class Solution: # @param board, a 2D array # Capture all regions by modifying the input board in-place. @@ -26,15 +29,15 @@ def solve(self, board): if not board: return q = collections.deque([]) - + for i in xrange(len(board)): q.append((i, 0)) q.append((i, len(board[0]) - 1)) - + for j in xrange(len(board[0])): q.append((0, j)) q.append((len(board) - 1, j)) - + while q: i, j = q.popleft() if board[i][j] in ['O', 'V']: @@ -44,7 +47,7 @@ def solve(self, board): board[x][y] == 'O': board[x][y] = 'V' q.append((x, y)) - + for i in xrange(len(board)): for j in xrange(len(board[0])): if board[i][j] != 'V': diff --git a/Python/target-sum.py b/Python/target-sum.py index 602767865..cb01825df 100644 --- a/Python/target-sum.py +++ b/Python/target-sum.py @@ -8,9 +8,9 @@ # Find out how many ways to assign symbols to make sum of integers equal to target S. # # Example 1: -# Input: nums is [1, 1, 1, 1, 1], S is 3. +# Input: nums is [1, 1, 1, 1, 1], S is 3. # Output: 5 -# Explanation: +# Explanation: # # -1+1+1+1+1 = 3 # +1-1+1+1+1 = 3 @@ -24,6 +24,9 @@ # The sum of elements in the given array will not exceed 1000. # Your output answer is guaranteed to be fitted in a 32-bit integer. +import collections + + class Solution(object): def findTargetSumWays(self, nums, S): """ diff --git a/Python/task-scheduler.py b/Python/task-scheduler.py index 4ee3eacc2..1e2bb7813 100644 --- a/Python/task-scheduler.py +++ b/Python/task-scheduler.py @@ -22,6 +22,9 @@ # The number of tasks is in the range [1, 10000]. # The integer n is in the range [0, 100]. +import collections + + class Solution(object): def leastInterval(self, tasks, n): """ @@ -34,7 +37,7 @@ def leastInterval(self, tasks, n): for task in tasks: count[task] += 1 max_count = max(max_count, count[task]) - + result = (max_count-1) * (n+1) for count in count.values(): if count == max_count: diff --git a/Python/the-maze-ii.py b/Python/the-maze-ii.py index 534ad0925..e651891d9 100644 --- a/Python/the-maze-ii.py +++ b/Python/the-maze-ii.py @@ -1,6 +1,9 @@ # Time: O(max(r, c) * wlogw) # Space: O(w) +import heapq + + class Solution(object): def shortestDistance(self, maze, start, destination): """ @@ -10,7 +13,7 @@ def shortestDistance(self, maze, start, destination): :rtype: int """ start, destination = tuple(start), tuple(destination) - + def neighbors(maze, node): for dir in [(-1, 0), (0, 1), (0, -1), (1, 0)]: cur_node, dist = list(node), 0 @@ -32,5 +35,5 @@ def neighbors(maze, node): visited.add(node) for neighbor_dist, neighbor in neighbors(maze, node): heapq.heappush(heap, (dist+neighbor_dist, neighbor)) - + return -1 diff --git a/Python/the-maze-iii.py b/Python/the-maze-iii.py index 02be0681a..ddcc087fe 100644 --- a/Python/the-maze-iii.py +++ b/Python/the-maze-iii.py @@ -1,6 +1,9 @@ # Time: O(max(r, c) * wlogw) # Space: O(w^2) +import heapq + + class Solution(object): def findShortestWay(self, maze, ball, hole): """ @@ -11,7 +14,7 @@ def findShortestWay(self, maze, ball, hole): """ ball, hole = tuple(ball), tuple(hole) dirs = {'u' : (-1, 0), 'r' : (0, 1), 'l' : (0, -1), 'd': (1, 0)} - + def neighbors(maze, node): for dir, vec in dirs.iteritems(): cur_node, dist = list(node), 0 @@ -24,7 +27,7 @@ def neighbors(maze, node): if tuple(cur_node) == hole: break yield tuple(cur_node), dir, dist - + heap = [(0, '', ball)] visited = set() while heap: @@ -34,5 +37,5 @@ def neighbors(maze, node): visited.add(node) for neighbor, dir, neighbor_dist in neighbors(maze, node): heapq.heappush(heap, (dist+neighbor_dist, path+dir, neighbor)) - + return "impossible" diff --git a/Python/the-maze.py b/Python/the-maze.py index 573eeebd4..0016d08c0 100644 --- a/Python/the-maze.py +++ b/Python/the-maze.py @@ -1,6 +1,9 @@ # Time: O(max(r, c) * w) # Space: O(w) +import collections + + class Solution(object): def hasPath(self, maze, start, destination): """ @@ -10,7 +13,7 @@ def hasPath(self, maze, start, destination): :rtype: bool """ start, destination = tuple(start), tuple(destination) - + def neighbors(maze, node): for dir in [(-1, 0), (0, 1), (0, -1), (1, 0)]: cur_node, dist = list(node), 0 @@ -32,5 +35,5 @@ def neighbors(maze, node): visited.add(node) for neighbor_dist, neighbor in neighbors(maze, node): queue.append((dist+neighbor_dist, neighbor)) - + return False diff --git a/Python/top-k-frequent-elements.py b/Python/top-k-frequent-elements.py index dd08c34ff..386c7dc11 100644 --- a/Python/top-k-frequent-elements.py +++ b/Python/top-k-frequent-elements.py @@ -7,13 +7,22 @@ # For example, # Given [1,1,1,2,2,3] and k = 2, return [1,2]. # -# Note: +# Note: # You may assume k is always valid, # 1 <= k <= number of unique elements. # Your algorithm's time complexity must be better # than O(n log n), where n is the array's size. # Bucket Sort Solution + +import collections + +try: + xrange # Python 2 +except NameError: + xrange = range # Python 3 + + class Solution(object): def topKFrequent(self, nums, k): """ @@ -25,7 +34,7 @@ def topKFrequent(self, nums, k): buckets = [[] for _ in xrange(len(nums)+1)] for i, count in counts.iteritems(): buckets[count].append(i) - + result = [] for i in reversed(xrange(len(buckets))): for j in xrange(len(buckets[i])): @@ -50,14 +59,13 @@ def topKFrequent(self, nums, k): p = [] for key, val in counts.iteritems(): p.append((-val, key)) - self.kthElement(p, k); + self.kthElement(p, k) result = [] for i in xrange(k): result.append(p[i][1]) return result - def kthElement(self, nums, k): def PartitionAroundPivot(left, right, pivot_idx, nums): pivot_value = nums[pivot_idx] @@ -67,7 +75,7 @@ def PartitionAroundPivot(left, right, pivot_idx, nums): if nums[i] < pivot_value: nums[i], nums[new_pivot_idx] = nums[new_pivot_idx], nums[i] new_pivot_idx += 1 - + nums[right], nums[new_pivot_idx] = nums[new_pivot_idx], nums[right] return new_pivot_idx @@ -81,7 +89,7 @@ def PartitionAroundPivot(left, right, pivot_idx, nums): right = new_pivot_idx - 1 else: # new_pivot_idx < k - 1. left = new_pivot_idx + 1 - + # Time: O(nlogk) # Space: O(n) @@ -93,4 +101,3 @@ def topKFrequent(self, nums, k): :rtype: List[int] """ return [key for key, _ in collections.Counter(nums).most_common(k)] - diff --git a/Python/top-k-frequent-words.py b/Python/top-k-frequent-words.py index d88d416bd..cf1ea8b3d 100644 --- a/Python/top-k-frequent-words.py +++ b/Python/top-k-frequent-words.py @@ -25,7 +25,12 @@ # Can you solve it in O(n) time with only O(k) extra space? # Quick Select Solution + +import collections +import heapq from random import randint + + class Solution(object): def topKFrequent(self, words, k): """ @@ -37,15 +42,14 @@ def topKFrequent(self, words, k): p = [] for key, val in counts.iteritems(): p.append((-val, key)) - self.kthElement(p, k); - + self.kthElement(p, k) + result = [] sorted_p = sorted(p[:k]) for i in xrange(k): result.append(sorted_p[i][1]) return result - def kthElement(self, nums, k): # O(n) on average def PartitionAroundPivot(left, right, pivot_idx, nums): pivot_value = nums[pivot_idx] @@ -55,7 +59,7 @@ def PartitionAroundPivot(left, right, pivot_idx, nums): if nums[i] < pivot_value: nums[i], nums[new_pivot_idx] = nums[new_pivot_idx], nums[i] new_pivot_idx += 1 - + nums[right], nums[new_pivot_idx] = nums[new_pivot_idx], nums[right] return new_pivot_idx @@ -70,7 +74,7 @@ def PartitionAroundPivot(left, right, pivot_idx, nums): else: # new_pivot_idx < k - 1. left = new_pivot_idx + 1 - + # Time: O(nlogk) # Space: O(n) # Heap Solution @@ -82,12 +86,15 @@ def topKFrequent(self, words, k): :rtype: List[str] """ class MinHeapObj(object): - def __init__(self,val): self.val = val + def __init__(self,val): + self.val = val def __lt__(self,other): return self.val[1] > other.val[1] if self.val[0] == other.val[0] else \ self.val < other.val - def __eq__(self,other): return self.val == other.val - def __str__(self): return str(self.val) + def __eq__(self,other): + return self.val == other.val + def __str__(self): + return str(self.val) counts = collections.Counter(words) min_heap = [] diff --git a/Python/transform-to-chessboard.py b/Python/transform-to-chessboard.py index b6cdbfae5..236bbe106 100644 --- a/Python/transform-to-chessboard.py +++ b/Python/transform-to-chessboard.py @@ -39,6 +39,10 @@ # - board will have the same number of rows and columns, a number in the range [2, 30]. # - board[i][j] will be only 0s or 1s. +import collections +import itertools + + class Solution(object): def movesToChessboard(self, board): """ @@ -60,4 +64,3 @@ def movesToChessboard(self, board): result += min(sum(int(i%2 != v) for i, v in enumerate(seq1, begin)) \ for begin in begins) / 2 return result - diff --git a/Python/unique-word-abbreviation.py b/Python/unique-word-abbreviation.py index f734f40c8..6d90c05df 100644 --- a/Python/unique-word-abbreviation.py +++ b/Python/unique-word-abbreviation.py @@ -1,7 +1,10 @@ -# Time: ctor: O(n), n is number of words in the dictionary. +# Time: ctor: O(n), n is number of words in the dictionary. # lookup: O(1) # Space: O(k), k is number of unique words. +import collections + + class ValidWordAbbr(object): def __init__(self, dictionary): """ @@ -12,7 +15,7 @@ def __init__(self, dictionary): for word in dictionary: abbr = self.abbreviation(word) self.lookup_[abbr].add(word) - + def isUnique(self, word): """ diff --git a/Python/valid-anagram.py b/Python/valid-anagram.py index 0477caec1..040bdc853 100644 --- a/Python/valid-anagram.py +++ b/Python/valid-anagram.py @@ -12,6 +12,10 @@ # You may assume the string contains only lowercase alphabets. # +import collections +import string + + class Solution: # @param {string} s # @param {string} t @@ -37,13 +41,13 @@ def isAnagram(self, s, t): return False return True - + def isAnagram2(self, s, t): return all([s.count(c)==t.count(c) for c in string.ascii_lowercase]) - + def isAnagram3(self, s, t): if len(s) != len(t): - return False + return False count = collections.defaultdict(int) for c in s: count[c] += 1 diff --git a/Python/validate-ip-address.py b/Python/validate-ip-address.py index 50be7762d..6a46a8a44 100644 --- a/Python/validate-ip-address.py +++ b/Python/validate-ip-address.py @@ -1,7 +1,7 @@ # Time: O(1) # Space: O(1) -# In this problem, your job to write a function to check whether a input string +# In this problem, your job to write a function to check whether a input string # is a valid IPv4 address or IPv6 address or neither. # # IPv4 addresses are canonically represented in dot-decimal notation, @@ -46,6 +46,9 @@ # # Explanation: This is neither a IPv4 address nor a IPv6 address. +import string + + class Solution(object): def validIPAddress(self, IP): """ @@ -64,7 +67,7 @@ def validIPAddress(self, IP): if len(blocks) == 8: for i in xrange(len(blocks)): if not (1 <= len(blocks[i]) <= 4) or \ - not all(c in string.hexdigits for c in blocks[i]): + not all(c in string.hexdigits for c in blocks[i]): return "Neither" return "IPv6" return "Neither" diff --git a/Python/word-abbreviation.py b/Python/word-abbreviation.py index ef666f0a3..87f1290ad 100644 --- a/Python/word-abbreviation.py +++ b/Python/word-abbreviation.py @@ -1,6 +1,9 @@ # Time: O(n * l) ~ O(n^2 * l^2) # Space: O(n * l) +import collections + + class Solution(object): def wordsAbbreviation(self, dict): """ @@ -9,7 +12,7 @@ def wordsAbbreviation(self, dict): """ def isUnique(prefix, words): return sum(word.startswith(prefix) for word in words) == 1 - + def toAbbr(prefix, word): abbr = prefix + str(len(word) - 1 - len(prefix)) + word[-1] return abbr if len(abbr) < len(word) else word diff --git a/Python/zigzag-iterator.py b/Python/zigzag-iterator.py index 9936e2d52..56fc22313 100644 --- a/Python/zigzag-iterator.py +++ b/Python/zigzag-iterator.py @@ -1,6 +1,9 @@ # Time: O(n) # Space: O(k) +import collections + + class ZigzagIterator(object): def __init__(self, v1, v2): diff --git a/Python/zuma-game.py b/Python/zuma-game.py index 1af644c93..99d25c947 100644 --- a/Python/zuma-game.py +++ b/Python/zuma-game.py @@ -25,11 +25,11 @@ # # Input:"G", "GGGGG" # Output: 2 -# Explanation: G -> G[G] -> GG[G] -> empty +# Explanation: G -> G[G] -> GG[G] -> empty # # Input: "RBYYBBRRB", "YRBGB" # Output: 3 -# Explanation: RBYYBBRRB -> RBYY[Y]BBRRB -> RBBBRRB -> RRRB -> B -> B[B] -> BB[B] -> empty +# Explanation: RBYYBBRRB -> RBYY[Y]BBRRB -> RBBBRRB -> RRRB -> B -> B[B] -> BB[B] -> empty # # Note: # You may assume that the initial row of balls on the table won’t have any 3 or @@ -40,6 +40,9 @@ # is called "hand" in the input. # Both input strings will be non-empty and only contain characters 'R','Y','B','G','W'. +import collections + + class Solution(object): def findMinStep(self, board, hand): """ @@ -63,18 +66,18 @@ def shrink(s): # Time: O(n), Space: O(n) for p in stack: result += [p[0]] * p[1] return result - + def find(board, c, j): for i in xrange(j, len(board)): if board[i] == c: return i return -1 - + def findMinStepHelper(board, hand, lookup): if not board: return 0 if not hand: return float("inf") if tuple(hand) in lookup[tuple(board)]: return lookup[tuple(board)][tuple(hand)] - + result = float("inf") for i in xrange(len(hand)): j = 0 @@ -82,7 +85,7 @@ def findMinStepHelper(board, hand, lookup): k = find(board, hand[i], j) if k == -1: break - + if k < len(board) - 1 and board[k] == board[k+1]: next_board = shrink(board[0:k] + board[k+2:]) next_hand = hand[0:i] + hand[i+1:]