20200108-20200112

Posted sky37

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了20200108-20200112相关的知识,希望对你有一定的参考价值。

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)

以上是关于20200108-20200112的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段——CSS选择器

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段6——CSS选择器

VSCode自定义代码片段——声明函数