244. Shortest Word Distance II - Medium
245. Shortest Word Distance III - Medium
246. Strobogrammatic Number - Easy
247. Strobogrammatic Number II - Medium
method: recursion
n =1 [0,1,8]
n = 2 [11, 88, 69, 96]
n = 3 [101, 111, 181, 808, 818, 888, 609, 619, 689, 906, 916, 986] we can get this answer by inserting [0,1,8] into the meddle of the solution when n = 2.
n = 4 we can get the answer by inserting [11, 88, 69, 96] into the solution when n = 2.
class Solution: def findStrobogrammatic(self, n: int) -> List[str]: if n == 0: return [""] if n == 1: return [‘0‘, ‘1‘, ‘8‘] if n == 2: return [‘11‘, ‘69‘, ‘88‘, ‘96‘] even = ["11","69","88","96", "00"] odd = ["0", "1", "8"] if n%2: pre, middle = self.findStrobogrammatic(n-1), odd else: pre, middle = self.findStrobogrammatic(n-2), even premid = (n-1) // 2 return [p[:premid] + c + p[premid:] for c in middle for p in pre]
248. Strobogrammatic Number III - Hard
249. Group Shifted Strings - Medium
250. Count Univalue Subtrees - Medium
251. Flatten 2D Vector - Medium
252. Meeting Rooms - Easy
253. Meeting Rooms II - Medium
I am always stuck with the heap solution.
class Solution: def minMeetingRooms(self, intervals: List[List[int]]) -> int: if not intervals or len(intervals) == 0: return 0 intervals.sort(key = lambda x:x[0]) heap = [] #just store the end time for interval in intervals: if heap and interval[0] >= heap[0]: heapq.heapreplace(heap, interval[1]) else: heapq.heappush(heap, interval[1]) # print(heap) return len(heap)
254. Factor Combinations - Medium
DFS
The condition for the res to append a path is len(path) > 0. Because we need all combinations.
The condition for the further step of dfs is if n % i == 0. The range for the i is [start, int(math.sqrt(n))+1]
class Solution: def getFactors(self, n: int) -> List[List[int]]: # 2 3 5 7 res = [] self.dfs( n,2, res, []) return res def dfs(self, n, start, res, path): if len(path) > 0: res.append(path+[n]) for i in range(start, int(math.sqrt(n))+1): if n % i == 0: self.dfs( n//i,i,res, path+[i] ) return res
255. Verify Preorder Sequence in Binary Search Tree - Medium
这个做法是单调栈的应用。用low = stack.pop() 来update每一个node的最小值。
class Solution: def verifyPreorder(self, preorder: List[int]) -> bool: if not preorder or len(preorder) == 0: return True stack = [] low = float(‘-inf‘) for p in preorder: if p < low: return False while stack and stack[-1] < p: low = stack.pop() stack.append(p) return True
以[5,2,1,3,6]举例, low一开始等于负无穷。5先进入stack,然后2,1都进入。3的时候,我们发现stack[-1] <p, 所以执行low = stack.pop()
然后把3 和6再依次入栈。返回True。
以[5,2,6,1,3] 为例。5 2 入栈之后,6把2压出栈,此时low是2. 下一个我们遇到的是1,1比2小,return False。
reuse the preorder array to get an O(1) space solution
class Solution: def verifyPreorder(self, preorder: List[int]) -> bool: if not preorder or len(preorder) == 0: return True i = 0 low = float(‘-inf‘) for p in preorder: if p < low: return False while i > 0 and p > preorder[i-1]: low = preorder[i-1] i -= 1 preorder[i] = p i += 1 return True
256. Paint House - Easy
257. Binary Tree Paths - Easy
258. Add Digits - Easy
259. 3Sum Smaller - Medium
261. Graph Valid Tree - Medium
# BFS
class Solution: def validTree(self, n: int, edges: List[List[int]]) -> bool: if len(edges) != n-1: return False if n == 1 and (not edges or len(edges) == 0): return True visited = set() graph = collections.defaultdict(set) for s, t in edges: graph[s].add(t) graph[t].add(s) q = collections.deque() q.append(edges[0][0]) while q: node = q.pop() if node in visited: return False visited.add(node) for neigh in graph[node]: q.appendleft(neigh) graph[neigh].remove(node) del graph[node] return not graph
#DFS
class Solution: def validTree(self, n: int, edges: List[List[int]]) -> bool: if len(edges) != n-1: return False if n == 1 and (not edges or len(edges) == 0): return True visited = set() graph = collections.defaultdict(set) for s, t in edges: graph[s].add(t) graph[t].add(s) stack = [] stack.append(list(graph.keys())[0]) while stack: node = stack.pop() if node in visited: return False visited.add(node) for neigh in graph[node]: stack.append(neigh) graph[neigh].remove(node) del graph[node] return not graph
# Union Find
class Solution: def validTree(self, n: int, edges: List[List[int]]) -> bool: nums = [-1] * n for s, t in edges: if not self.union(nums, s, t): return False return len(edges) == n-1 def union(self, nums, s, t): ss = self.find(nums, s) tt = self.find(nums, t) if ss == tt: return False nums[ss] = tt return True def find(self, nums, s): if nums[s] == -1: return s return self.find(nums, nums[s])
263. Ugly Number - Easy
use for p in [2,3,5] to divide the num.
264. Ugly Number II - Medium
265. Paint House II - Hard
cost[i][j]: represent the cost of ith house using jth paint.
For each house, we first find the smallest color previous house used. And then find the second smallest cost. For each color in this house,
if this is the smallest color previous house used, then cost[i][j] += second smallest. Else, cost[i][j] += smallest.
266. Palindrome Permutation - Easy
267. Palindrome Permutation II - Medium
Step1: construct a counter for the string (c =collections.Counter(s) )
Step2: find the mid and base for this string. Mid is the character that satisfies the condition that c[cc] % 2 != 0. If there are two characters that are c[cc] % 2 != 0, we could just return an empty list because this is not a palindromic permutation. base+=cc*( c[cc] // 2)
Step3: use dfs method. self.dfs(s, res, base, start, mid). The return condition is start == len(base), res.append(base + mid +base[::-1]).
We change the position of the character in the base with the start character to get a new base.
perm = base[:start] + base[i]+ base[start+1:i] + base[start] + base[i+1:]
class Solution: def generatePalindromes(self, s: str) -> List[str]: c = collections.Counter(s) res = [] mid = ‘‘ base = ‘‘ for cc in c: if c[cc] %2 != 0: if mid: return [] else: mid = cc base+=cc*( c[cc] // 2) self.dfs(s, res, base, 0, mid) return res def dfs(self, s, res, base, start, mid): if start == len(base): res.append(base + mid +base[::-1]) return for i in range(start, len(base)): if i > start and (base[i] == base[i-1] or base[i] == base[start]): continue if i == start: perm = base else: perm = base[:start] + base[i]+ base[start+1:i] + base[start] + base[i+1:] # print(perm) self.dfs(s, res, perm, start+1, mid)
268. Missing Number - Easy
269. Alien Dictionary - Hard
270. Closest Binary Search Tree Value - Easy
272. Closest Binary Search Tree Value II - Hard
274. H-Index - Medium
counting sort O(n)
when we deal with the paper, we need to use the min(c, n) to be the index in the paper.
Besides, the value we want to find is the largest k that satisfies k <= s, so we use a while loop: while k > s. When we find a k that satisfies less than or equal to s, we just return the k.
class Solution: def hIndex(self, citations: List[int]) -> int: if not citations or len(citations) == 0: return 0 n = len(citations) paper = [0] * (n+1) for c in citations: paper[min(c, n)] += 1 k = n s = paper[-1] while k > s: k -= 1 s += paper[k] return k
275. H-Index II - Medium
binary search
276. Paint Fence - Easy
277. Find the Celebrity - Medium
278. First Bad Version - Easy
279. Perfect Squares - Medium
# BFS
class Solution: def numSquares(self, n: int) -> int: q = collections.deque() q.append((n, 0)) visited = set() visited.add(n) while q: for _ in range(len(q)): cur, num = q.pop() if cur == 0: return num for i in range( 1, int(math.sqrt(n))+1): val = cur - i *i if val in visited: continue visited.add(val) q.appendleft((val, num+1)) return num
# DP
class Solution: def numSquares(self, n: int) -> int: square_numbers = [i**2 for i in range(int(math.sqrt(n))+1)] dp = [float(‘inf‘)] * (n+1) dp[0] = 0 for i in range(1, n+1): for square in square_numbers: if i < square: continue dp[i] = min(dp[i], dp[i-square]+1) #print(dp) return dp[-1]
280. Wiggle Sort - Medium
281. Zigzag Iterator - Medium
282. Expression Add Operators - Hard
dfs: def dfs(self, num, target, res, path, cur, last,idx)
The condition to append the path is if idx == len(num) and cur == target.
class Solution: def addOperators(self, num: str, target: int) -> List[str]: res = [] self.dfs(num, target, res, "", 0,0, 0) return res def dfs(self, num, target, res, path, cur, last,idx): if idx == len(num) and cur == target: res.append(path) return res for i in range(idx+1, len(num)+1): val = int(num[idx:i]) if i == idx+1 or (i> idx+1 and num[idx]!= ‘0‘): if not path: self.dfs(num, target, res, num[idx:i], val, val, i) else: self.dfs(num, target, res, path+‘+‘+num[idx:i], cur+val, val, i) self.dfs(num, target, res, path+‘-‘+num[idx:i], cur-val, -val, i) self.dfs(num, target, res, path+‘*‘+num[idx:i], cur-last+last*val, last*val, i)
283. Move Zeroes - Easy
285. Inorder Successor in BST - Medium
Step1: deal with the situation that p is in the right of the root.
if p.right:
p = p.right
while p.left:
p = p.left
return p
Step2: if p is in the left side of the root. We use an iterative method to get the answer.
class Solution: def inorderSuccessor(self, root: ‘TreeNode‘, p: ‘TreeNode‘) -> ‘TreeNode‘: if not root or not p: return 0 if p.right: p = p.right while p.left: p = p.left return p stack = [] inorder = float(‘-inf‘) while stack or root: while root: stack.append(root) root = root.left # go as left as you can root = stack.pop() if inorder == p.val: return root inorder = root.val root = root.right return None
286. Walls and Gates - Medium
BFS
287. Find the Duplicate Number - Medium
Floyd‘s Tortoise and Hare (Cycle Detection)
class Solution: def findDuplicate(self, nums: List[int]) -> int: if not nums or len(nums) == 0: return -1 t = nums[0] h = nums[0] while True: t = nums[t] h = nums[nums[h]] if t == h: break p1 = nums[0] p2 = h while p1 != p2: p1 = nums[p1] p2 = nums[p2] return p1
288. Unique Word Abbreviation - Medium
289. Game of Life - Medium
290. Word Pattern - Easy
pattern "jquery"
str "jquery" ===> this is False
292. Nim Game - Easy
293. Flip Game - Easy
294. Flip Game II - Medium
in the recursion method, remeber to use memorization to optimize.
295. Find Median from Data Stream - Hard
from heapq import * class MedianFinder: def __init__(self): """ initialize your data structure here. """ self.small = [] self.large = [] def addNum(self, num: int) -> None: if len(self.small) == len(self.large): heapq.heappush(self.large, -heappushpop(self.small, -num)) else: heapq.heappush(self.small, -heappushpop(self.large, num)) def findMedian(self) -> float: if len(self.small) == len(self.large): return ((-self.small[0]) + self.large[0]) / 2 else: return self.large[0]
Therefore to add a number, we have 3 O(log n) heap operations. Luckily the heapq provided us a function "heappushpop" which saves some time by combine two into one. The document says:
Push item on the heap, then pop and return the smallest item from the heap. The combined action runs more efficiently than heappush() followed by a separate call to heappop().
Altogether, the add operation is O(logn), The findMedian operation is O(1).
!!!
when the len(s) == len(l), we will push the new num into l. So when they have different lengths, findMedian should return the smallest number in the l.
296. Best Meeting Point - Hard
class Solution: def minTotalDistance(self, grid: List[List[int]]) -> int: if not grid or len(grid) == 0 or len(grid[0]) == 0: return 0 rows = len(grid) cols = len(grid[0]) r = [i for i in range(rows) for j in range(cols) if grid[i][j]] c = [j for i in range(rows) for j in range(cols) if grid[i][j]] r.sort() c.sort() mid_r = r[len(r) // 2] mid_c = c[len(c)//2] return sum(abs(i-mid_r) for i in r) + sum(abs(j-mid_c) for j in c)
298. Binary Tree Longest Consecutive Sequence - Medium
bottom to up
class Solution: def longestConsecutive(self, root: TreeNode) -> int: if not root: return 0 self.res = 0 self.help(root) return self.res def help(self, root): if not root: return 0 l = self.help(root.left) + 1 r = self.help(root.right) + 1 if root.left and root.left.val != root.val + 1: l = 1 if root.right and root.right.val != root.val + 1: r = 1 self.res = max(self.res, max(l, r)) return max(l, r)
up to the bottom
class Solution: def longestConsecutive(self, root: TreeNode) -> int: if not root: return 0 self.res = 0 self.help(root, None, 0) return self.res def help(self, root, parent, count): if not root: return if parent and root.val == parent.val +1: count += 1 else: count = 1 self.res = max(self.res, count) self.help(root.left, root, count) self.help(root.right, root, count)
299. Bulls and Cows - Easy
class Solution: def getHint(self, secret: str, guess: str) -> str: if not secret: return "0A0B" bull = 0 cow = 0 s = {} g = {} for i in range(len(secret)): if secret[i] == guess[i]: bull+=1 else: s[secret[i]] = s.get(secret[i], 0)+1 g[guess[i]] = g.get(guess[i], 0)+1 for ss in s: if ss in g: cow += min(s[ss], g[ss]) return "{0}A{1}B".format(bull, cow)
原文地址:https://www.cnblogs.com/sky37/p/12190142.html