Basic introduction to LeetCode





What do you need to know about LeetCode? This article will give you a detailed understanding, welcome to collect!

Python syntax

  
  
  
  
  
reduce(function, iterable[, initializer])    reduce(lambda x,y:x * y,ns) # 数组之乘积 (ns[0] * ns[1]) * ns[2]    reduce(lambda x,y:x + y,ns) # 数组之和# 记忆化搜索@functools.lru_cache(None)res = helper(0,N,0)helper.cache_clear()tuple(ns) 可以hash做参数# 大根堆q = list(map(lambda x:-x,ns))heapq.heapify(q)key = -heapq.heappop(q)# 过滤函数filter(function, iterable)    filter(lambda x: 2 < x < 10 and x % 2 == 0, range(18))    filter(dfs, range(len(graph)))# 除数div, mod = divmod(sum(ns), 4)random.randint(i,len(self.ns)-1)#第一个降序,第二个升序sorted(pss,key = lambda x:[x[0],-x[1]])
# 不可变str 常见函数split(sep=None, maxsplit=-1) # 以sep来分割字符串strip([chars]) # 去除首末两端的字符, 默认是 \r,\n," "join(iterable) # 将iterable内的元素拼接成字符串,如','.join(['leet', 'code'])="leet,code"replace(old, new[, count]) # 字符串替换, old to newcount(sub[, start[, end]]) # 统计子字符串sub的个数startswith(prefix[, start[, end]]) # 以prefix开始的字符串endswith(suffix[, start[, end]]) # 以suffix结束的字符串cs in chrs: # chrs 中包含 cs
# deque 常见函数queue = deque([iterable[, maxlen]])queue.append(val) # 往右边添加一个元素queue.appendleft(val) # 往左边添加一个元素queue.clear() # 清空队列queue.count(val) # 返回指定元素的出现次数queue.insert(val[, start[, stop]]) # 在指定位置插入元素queue.pop() # 获取最右边一个元素,并在队列中删除queue.popleft() # 获取最左边一个元素,并在队列中删除queue.reverse() # 队列反转queue.remove(val) # 删除指定元素queue.rotate(n=1) # 把右边元素放到左边
# list 常见函数lst.sort(*, key=None, reverse=False)lst.append(val) # 也可以 lst = lst + [val]lst.clear() # 清空列表lst.count(val) # val个数lst.pop(val=lst[-1]) # (默认)从末端移除一个值lst.remove(val) # 移除 vallst.reverse() # 反转lst.insert(i, val) # 在 i 处插入 val
# 字典dict 常见函数d = defaultdict(lambda : value) # 取到不存在的值时不会报错,用{}时、需要设置get的default值pop(key[, default]) # 通过键去删除键值对(若没有该键则返回default(没有设置default则报错))setdefault(key[, default]) # 设置默认值update([other]) # 批量添加get(key[, default]) # 通过键获取值(若没有该键可设置默认值, 预防报错)clear() # 清空字典keys() # 将字典的键组成新的可迭代对象values() # 将字典中的值组成新的可迭代对象items() # 将字典的键值对凑成一个个元组, 组成新的可迭代对象dict1 = dict2 #两个字典完全相等,滑窗时可用
# 集合set 常见函数s = set(lambda : value)add(elem) # 向集合中添加数据update(*others) # 迭代着增加clear() # 清空集合discard(elem) # 删除集合中指定的值(不存在则不删除)
# 堆heapq 常见函数heap = [] # 建堆heapq.heappush(heap,item) # 往堆中插入新值heapq.heappop(heap) # 弹出最小的值heap[0] # 查看堆中最小的值, 不弹出heapq.heapify(x) # 以线性时间将一个列表转为堆heapq.heappoppush(heap, item) # 弹出最小的值.并且将新的值插入其中.heapq.merge(*iterables, key=None, reverse=False) # 将多个堆进行合并heapq.nlargest(n, iterable, key=None) # 从堆中找出最大的 n 个数,key的作用和sorted( )方法里面的key类似, 用列表元素的某个属性和函数作为关键字heapq.nsmallest(n, iterable, key=None) # 从堆中找出最小的 n 个数, 与 nlargest 相反

# 二分查找函数bisect.bisect_left(ps, T, L=0, R=len(ns)) #二分左边界bisect.bisect_right(ps, T, L=0, R=len(ns)) #二分右边界 bisect.insort_left(a, x, lo=0, hi=len(a)) # 二分插入到左侧bisect.insort_right(a, x, lo=0, hi=len(a)) # 二分插入到右侧
# bit操作& 符号,x & y ,会将两个十进制数在二进制下进行与运算| 符号,x | y ,会将两个十进制数在二进制下进行或运算^ 符号,x ^ y ,会将两个十进制数在二进制下进行异或运算<< 符号,x << y 左移操作,最右边用 0 填充>> 符号,x >> y 右移操作,最左边用 0 填充~ 符号,~x ,按位取反操作,将 x 在二进制下的每一位取反
# 整数集合set位运算# 整数集合做标志时,可以做参数加速运算vstd 访问 i :vstd | (1 << i)vstd 离开 i :vstd & ~(1 << i)vstd 不包含 i : not vstd & (1 << i)
并集 :A | B交集 :A & B全集 :(1 << n) - 1补集 :((1 << n) - 1) ^ A子集 :(A & B) == B判断是否是 2 的幂 :A & (A - 1) == 0最低位的 1 变为 0 :n &= (n - 1) while n: n &= n - 1 ret += 1最低位的 1:A & (-A),最低位的 1 一般记为 lowbit(A)
# ^ :匹配字符串开头# [\+\-]:代表一个+字符或-字符# ? :前面一个字符可有可无# \d :一个数字# + :前面一个字符的一个或多个# \D :一个非数字字符# * :前面一个字符的0个或多个matches = re.match('[ ]*([+-]?\d+)', s)


backpack template

0-1 backpack problem on "Likou" :
  • Combination question template
#0-1背包,不可重复for n in ns:     for i in range(T, n-1, -1):        dp[i] = max(dp[i], dp[i - n] + ws[i])#完全背包,可重复,无序,算重量for n in ns:     for i in range(n, T+1):        dp[i] = max(dp[i], dp[i - n] + ws[i]) #完全背包,可重复,有序,算次数     for i in range(1, T+1):    for n in ns:        dp[i] += dp[i-n]
  • 377 Combination Sum IV
  • 494 goals and
  • 518 Change Exchange II

  • True, False question
dp[i] |= dp[i-num]
  • 139 word splitting
  • 416 Split equal sum subsets

#特殊的可以使用bit数组


  • Maximum and minimum problems:

dp[i] = min(dp[i], dp[i-num]+1)dp[i] = max(dp[i], dp[i-num]+1)
  • 47 4 ones and zeros

  • 322 Change exchange


Question 879 of "Likou" : Profit Plan (Difficult); Question 1449 of "Likou" : The sum of digital costs is the maximum number of the target value (difficult).


Traceback template

  
  
  
  
  
# 回溯算法,复杂度较高2^n或者N!,因为回溯算法就是暴力穷举,可用lru剪枝@functools.lru_cache(None)def backtrack(路径, 选择列表):    if 满足结束条件:        结果.append(路径)        return    for 选择 in 选择列表:    # 核心代码段          if vst[i]:   # 辅助数组,减枝          continue        做出选择        递归执行backtrack        撤销选择


"Pruning" Question 46 All Arrangements Question 47 All Arrangements ②

# 剪枝def backtrack(temp_list, length):    if length == n:      res.append(temp_list)    for i in range(n):      if not visited[i]:          visited[i] = 1          backtrack(temp_list + [nums[i]], length + 1)          visited[i] = 0

"Index Traversal" Question 78 | Question 47 ② | Question 131 Split String
   
   
   
   
   
第 **39 **题 组合 | 第 **40** 题 组合② | 第 **216** 题 组合③
# 索引遍历def helper1(idx, n, temp_list):  if temp_list not in res:    res.append(temp_list)  for i in range(idx, n):    helper1(i + 1, n, temp_list + [nums[i]])

Question 22 of "Resource Consumption" boast generation
   
   
   
   
   
# 资源消耗 def backtrack(S, L, R): if not L and not R: ans.append(''.join(S)) return if L : backtrack(S + ['('], L-1, R) if R > L : backtrack(S + [')'], L, R-1)

"Resource Consumption" Question 93 Restoring IP
   
   
   
   
   
资源消耗 def backtrack(i, tmp, flag): if i == n and flag == 0: res.append(tmp[:-1]) elif i<n and s[i] == '0': backtrack(i + 1, tmp + s[i] + ".", flag - 1) elif flag : for j in range(i, min(n,i + 3)): if 0 < int(s[i:j + 1]) <= 255: backtrack(j + 1, tmp + s[i:j + 1] + ".", flag - 1)

"Resource Consumption" Question 17 Phone Number
   
   
   
   
   
# 资源消耗 def dfs(path, remains): if not remains: res.append(path[:]) return for i in range(len(remains)): dfs(path + [remains[i]], remains[:i] + remains[i+1:])
# 套模板 def dfs(pth,idx): if idx == len(ds): res.append(pth) return for c in dic[ds[idx]]: dfs(pth + c, idx + 1)

"Multiple Limits" Problem 37 Solving Sudoku | Problem 51 N Queen
  
  
  
  
  
# 多重限制def backtrack(pos):  if pos == n:    return True  i, j = empty[pos]  for num in row[i] & col[j] & block[bidx(i, j)]:    row[i].remove(num)    col[j].remove(num)    block[bidx(i, j)].remove(num)    board[i][j] = str(num)    if backtrack(pos + 1): return True    row[i].add(num)    col[j].add(num)    block[bidx(i, j)].add(num)


"Recursion" Question 10 Regular Matching

# 递归def isMatch(self, s: str, p: str) -> bool:  if not p:     return not s  f = bool(s and p[0] in {s[0],'.'})  if len(p) >= 2 and p[1] == "*":    return self.isMatch(s, p[2:]) or f and self.isMatch(s[1:], p)  else:    return f and self.isMatch(s[1:], p[1:])


And look up the template

  
  
  
  
  
#虚拟节点用以连接某一特征的全部节点,类似于链表的preHeaddummy parent = {}size = collections.defaultdict(lambda:1)cnt = 0def find(x):    parent.setdefault(x,x)    while x != parent[x]:        x = parent[x]        #路径压缩 parent[x] = parent[parent[x]];    return xdef union(x,y):    nonlocal cnt    if connected(x,y): return    # 小的树挂到大的树上, 使树尽量平衡    xP = find(x)    yP = find(y)    if size[hP] < size[yP]:        parent[xP] = yP    else:        parent[yP] = xP    size[xP] += size[yP]    # 优化结束    parent[find(x)] = find(y)    # 不优化    cnt -= 1    return size[xP]def connected(x, y):    return find(x) == find(y)def add(self,x):    if x not in parent:        parent[x] = None        cnt += 1# 检查是否有环for a, b in edges:    if connected(a, b):         return True    union(a, b)# 将每个集合组成以头为key的字典res = collections.defaultdict(list)for e in e2n:    res[uf.find(e)].append(e)

Topological sort template

  
  
  
  
  
# 【拓扑排序模板】ins = [0] * nous = collections.defaultdict(list)for cur, pre in ps:    ins[cur] += 1              #入度    ous[pre].append(cur)    #出度res = list(filter(lambda x:ins[x]==0, range(n)))q = collections.deque(res)while q:    pre = q.popleft()    for cur in ous[pre]:   #释放出度队列        ins[cur] -= 1        if not ins[cur]:             q.append(cur)  #入度为0解锁            res.append(cur)

Monotone stack template


  
  
  
  
  
# s中一般存索引for i in range(len(ns):    while stack and ns[stack[-1]] <= ns[i]: # 单调递减栈        stack.pop()    # 业务逻辑    stack.append(i)


"Monotonically Increasing" Question 84: Find the Maximum Rectangle

  
  
  
  
  
# 第 **84** 题 求最大矩形for i in range(len(hs)):    while s and hs[i] < hs[s[-1]]:        base = s.pop()        if s:            H = hs[base]            W = i - s[-1] - 1 # 当前弹出的做高,当前与次小做宽            res = max(res, H * W)    s.append(i)


"Monotonically increasing, consider the remainder" Question 316 Remove duplicate characters

  
  
  
  
  
# 第 **316** 题 去除重复字符for i,c in enumerate(ss):    if c not in s:        while s and c < s[-1] and s[-1] in ss[i:]:            s.pop()        s.append(c)


"Monotonically Decreasing" Question 42: Collecting Rainwater

  
  
  
  
  
# 第 **42** 题 接雨水for i in range(len(hgt)):    while stack and hgt[i] > hgt[stack[-1]]: #递减栈        base = stack.pop()        if stack:            LH = hgt[stack[-1]]            W = i - stack[-1] - 1            H = min(LH,hgt[i]) - hgt[base]            res += W * H     stack.append(i)


"Monotonically Decreasing" Question 739 Daily Temperature

  
  
  
  
  
# 第 **739** 题 每日温度for i in range(len(T)-1,-1,-1):    while s and T[s[-1]] <= T[i] :   #递减栈        s.pop()    res[i] = s[-1] - i if s else 0    s.append(i)

bipartite template

# 1355579 T=5 => 13(5)55579 返回2# ps[i-1] < ps[i] <= ps[i+1]bisect.bisect_left(ps, T, L=0, R=len(ns))  # 1355579 T=5 => 13555(5)79 返回5# ps[i-1] <= ps[i] < ps[i+1]bisect.bisect_right(ps, T, L=0, R=len(ns))  bisect.bisect(ps, T, L=0, R=len(ns))


"Median Return" Question 33 Searching a Rotated Sorted Array | Question 374 Guessing the Number Size | Question 69 Square Root of x

# 中位返回while L <= R:    M = (L + R) // 2    if nums[M] == T:        return M    elif nums[M] < T:        L = M + 1    else:        R = M - 1


"Region Compression" Question 278, the first wrong version | Question 162, finding the peak value | Question 153, finding the minimum value of the array

# 区域压缩while L < R:    M = (L + R) // 2    if need in s[L:M]:        R = M    else:        L = M + 1

Dynamic programming template


▐Single string problem  


  • 70 Stair climbing problem

  • 801 Minimum number of swaps to increment the sequence

  • 746 Climb the stairs with minimum cost

  • 300 longest rising subsequence

   
   
   
   
   
# 依赖前单个元素 dp[i] = dp[i-1] + ns[i] # 依赖前部区域元素 for i in range(n) for j in range(i) dp[i] = min(dp[i], f(dp[j])


▐Single   string plus status problem

  • 887 Egg dropped
# 鸡蛋掉落while cur[K] < N:             # 还剩 j 个蛋 测 ans 次 覆盖多少层    for j in range(1, K + 1): # 覆盖总层数 碎了 -1 次层数 + 1 + 没碎 -1 次层数        cur[j] = prev[j - 1] + 1 + prev[j]    ans += 1    prev = copy.deepcopy(cur)


  • 813 Maximum average grouping

   
   
   
   
   
# 813 最大平均值分组 for k in range(K-1): #循环k次 for i in range(N): #每次均依赖上次的结果 for j in range(i+1, N): dp[i] = max(dp[i], avrg(i, j) + dp[j])

  • 410 Split array maximum value
   
   
   
   
   
# 410 分割数组最大值 for k in range(1,K): for i in range(N): for j in range(i): # 0~i中分 k 段最大 即为 # 0~j中分k-1段最大 和 j到i的前缀和的最大 dp[i][k] = min(dp[i][k], max(dp[j][k-1], ps[i+1] - ps[


▐Classic   double string LCS problem

   
   
   
   
   
# 经典双串LCS问题 dp = [[0] * (M+1) for _ in range(N+1)] for i in range(N): for j in range(M): if t1[i] == t2[j] : dp[i+1][j+1] = dp[i][j] + 1 else : dp[i+1][j+1] = max(dp[i][j+1],dp[i+1][j])


▐Interval   dynamic programming

  • 5 longest palindrome substring
  • 647 Most palindromic skewers

  • 516 longest palindrome subsequence

  • 1312 The longest number of palindrome insertions


# dp[i][j] 代表从 i 到 j 的最长子串满足条件的数量# i-- < j++  ==> i 在 0~j 范围内 --dp = [[0] * (N) for _ in range(N)]for j in range(N):    dp[j][j] = 1    for i in range(j-1,-1,-1):        if ss[i] == ss[j]:            dp[i][j] = dp[i+1][j-1] +2        else :            dp[i][j] = max(dp[i+1][j],dp[i][j-1])


▐Interval   divide and conquer dynamic programming


4 86 Predict the winner: https://leetcode-cn.com/problems/predict-the-winner/?spm=ata.21736010.0.0.49ae7ec0sfNWbz

312 Burst Balloons: https://ata.atatech.org/articles/***https://leetcode-cn.com/problems/burst-balloons/***?spm=ata.21736010.0.0.49ae7ec0sfNWbz

664 Strange printer: https://ata.atatech.org/articles/***https://leetcode-cn.com/problems/strange-printer/***?spm=ata.21736010.0.0.49ae7ec0sfNWbz

546 Remove boxes: https://ata.atatech.org/articles/***https://leetcode-cn.com/problems/remove-boxes/***?spm=ata.21736010.0.0.49ae7ec0sfNWbz

  
  
  
  
  

# 区间分治动态规划

def helper(self, ns: List[int]) : N = len(ns) dp = [[0] * N for _ in range(N+1)] for l in range(N): # 长度从小到大 for i in range(N-l): # 以 i 为 开头 j = i + l # 以 j 为 终点 for k in range(i,j): # 以 k 为分割点,进行分治 // Todo 业务逻辑


"Cattleya number"

# 卡特兰数g(n) = g(0)*g(n-1) + g(1)*g(n-2) ...g(n-1)*g(0)dp=[1] + [0] * nfor i in range(1,n+1):    for j in range(1,i+1):        dp[i] += dp[j-1] * dp[i-j]

sliding window


  
  
  
  
  
    
    
    
    
    
"""给定待查串s和目标串t""" nd, wd = {}, {} nd = collections.Counter(s1) L, R = 0, 0 cnt = 0 # 满足条件个数 while R < len(s): # 窗口右边界不断扩大,本质是搜索问题的可能解 c = s[R] # 即将加入到窗口中的字符 R += 1 更新窗口中的数据 while 满足窗口收缩条件:# 窗口的左边界收缩,本质是优化可行解 记录或返回结果 d = s[L] # 即将从窗口中删除的字符 L += 1 更新窗口中的数据 return 结果
# 固定窗口 ,比滑动窗口更快一些 i = j = cnt = 0 for j in range(len(A)): if A[j] == 0: cnt += 1 if cnt > K: #不满足时 平移 if A[i] == 0: cnt -= 1 i += 1 return j - i + 1
for j in range(len(A)): if A[j] == 0: cnt += 1 while cnt > K: if A[i] == 0: cnt -= 1 i += 1 res = max(res, j - i + 1) return res

prefix sum


"Accumulate and save positions"
1371 The longest even vowel subarray
525 longest equal 01 subarray
325 The longest sum is k subarrays
# 前缀和初始化psd = {0: -1}  for i in range(len(s)):    t ^= cd.get(s[i], 0) # 业务逻辑    if t not in psd:        psd[t] = i       # 第一次存入数组    else:        ans = max(ans, i - psd[t]) #已存入则开始计算

"Accumulate and save quantities"
  • 560 The number of subarrays whose sum is K
  • Statistically graceful subarrays
# 累加和存数量psd = {0:1}for i in range(len(ns)):    s += ns[i]    if s - T in psd:        ans += psd[s - T] # 存数量    psd[s] = psd.get(s,0) + 1

"Modulo K state prefix sum"
  • 523 Subarray whose consecutive sum is k times (stored in index)
  • 974 and the number of subarrays divisible by k (number of storages)
# 模K状态前缀和psd = {0:-1}ans = s = 0for i in range(len(ns)):    s += ns[i]                # 业务逻辑    if T != 0: s %= abs(T)    # 模k状态做key,索引做值    if s not in psd:        psd[s] = i    elif i - psd[s] > 1:        return True


"Matrix prefix sum"

  • 363 The maximum sum of values ​​not exceeding K

  • 1074 The number of submatrices whose sum is the target value

# 矩阵前缀和for i in range(m):        #固定左边界    ps = [0] * n    for j in range(i, m): #固定右边界        psS = 0            dct = {0:1}       #初始只有一种可能        for k in range(n): # 以高做前缀和            ps[k] += mtx[j][k]          # 每行前缀和            psS += ps[k]                # n行前缀和            cnt += dct.get(psS - T, 0)  # 满足条件cnt            dct[psS] = dct.get(psS,0) + 1 # 保存当前状态return cnt


double pointer


# 双指针def removeElement(self, ns: List[int], val: int) -> int:    slow = 0    n = len(ns)    for fast in range(n):        if ns[fast] != val:            ns[slow] = ns[fast]            slow += 1    return slow


depth first


"Binary tree traversal template"

# 递归# 时间复杂度:O(n),n为节点数,访问每个节点恰好一次。# 空间复杂度:空间复杂度:O(h),h为树的高度。最坏情况下需要空间O(n),平均情况为O(logn)
# 递归1:二叉树遍历最易理解和实现版本class Solution: def preOrd(self, root: TreeNode) -> List[int]: if not root: return [] # 前序递归 return [root.val] + self.preOrd(root.left) + self.preOrd(root.right) # # 中序递归 # return self.inOrd(root.left) + [root.val] + self.inOrd(root.right) # # 后序递归 # return self.postOrd(root.left) + self.postOrd(root.right) + [root.val]
# 递归2:通用模板,可以适应不同的题目,添加参数、增加返回条件、修改进入递归条件、自定义返回值class Solution: def preOrd(self, root: TreeNode) -> List[int]: def dfs(cur): if not cur: return # 前序递归 res.append(cur.val) dfs(cur.left) dfs(cur.right) # # 中序递归 # dfs(cur.left) # res.append(cur.val) # dfs(cur.right) # # 后序递归 # dfs(cur.left) # dfs(cur.right) # res.append(cur.val) res = [] dfs(root) return res

# 迭代# 时间复杂度:O(n),n为节点数,访问每个节点恰好一次。# 空间复杂度:O(h),h为树的高度。取决于树的结构,最坏情况存储整棵树,即O(n)# 迭代1:前序遍历最常用模板(后序同样可以用)class Solution: def preOrd(self, root: TreeNode) -> List[int]: if not root: return [] res = [] stack = [root] # # 前序迭代模板:最常用的二叉树DFS迭代遍历模板 while stack: cur = stack.pop() res.append(cur.val) if cur.right: stack.append(cur.right) if cur.left: stack.append(cur.left) return res
# # 后序迭代,相同模板:将前序迭代进栈顺序稍作修改,最后得到的结果反转 # while stack: # cur = stack.pop() # if cur.left: # stack.append(cur.left) # if cur.right: # stack.append(cur.right) # res.append(cur.val) # return res[::-1]
# 迭代1:层序遍历最常用模板class Solution: def levelOrder(self, root: TreeNode) -> List[List[int]]: if not root: return [] q = deque([root]) res = [] while q : l = [] for i in range(len(q)) : t = q.popleft() l.append(t.val) if t.left : q.append(t.left) if t.right : q.append(t.right) res.append(l) return res

# 迭代2:前、中、后序遍历通用模板(只需一个栈的空间)class Solution: def inOrd(self, root: TreeNode) -> List[int]: res = [] stack = [] cur = root # 中序,模板:先用指针找到每颗子树的最左下角,然后进行进出栈操作 while stack or cur: while cur: stack.append(cur) cur = cur.left cur = stack.pop() res.append(cur.val) cur = cur.right return res
# # 前序,相同模板 # while stack or cur: # while cur: # res.append(cur.val) # stack.append(cur) # cur = cur.left # cur = stack.pop() # cur = cur.right # return res
# # 后序,相同模板 # while stack or cur: # while cur: # res.append(cur.val) # stack.append(cur) # cur = cur.right # cur = stack.pop() # cur = cur.left # return res[::-1]

# 迭代3:标记法迭代(需要双倍的空间来存储访问状态):# 前、中、后、层序通用模板,只需改变进栈顺序或即可实现前后中序遍历,# 而层序遍历则使用队列先进先出。0表示当前未访问,1表示已访问。class Solution: def preOrd(self, root: TreeNode) -> List[int]: res = [] stack = [(0, root)] while stack: flag, cur = stack.pop() if not cur: continue if flag == 0: # 前序,标记法 stack.append((0, cur.right)) stack.append((0, cur.left)) stack.append((1, cur))
# # 后序,标记法 # stack.append((1, cur)) # stack.append((0, cur.right)) # stack.append((0, cur.left))
# # 中序,标记法 # stack.append((0, cur.right)) # stack.append((1, cur)) # stack.append((0, cur.left)) else: res.append(cur.val) return res
# # 层序,标记法 # res = [] # queue = [(0, root)] # while queue: # flag, cur = queue.pop(0) # 注意是队列,先进先出 # if not cur: continue # if flag == 0: # 层序遍历这三个的顺序无所谓,因为是队列,只弹出队首元素 # queue.append((1, cur)) # queue.append((0, cur.left)) # queue.append((0, cur.right)) # else: # res.append(cur.val) # return res


# 莫里斯遍历# 时间复杂度:O(n),n为节点数,看似超过O(n),有的节点可能要访问两次,实际分析还是O(n)# 空间复杂度:O(1),如果在遍历过程中就输出节点值,则只需常数空间就能得到中序遍历结果,空间只需两个指针。# 如果将结果储存最后输出,则空间复杂度还是O(n)。
# PS:莫里斯遍历实际上是在原有二叉树的结构基础上,构造了线索二叉树,# 线索二叉树定义为:原本为空的右子节点指向了中序遍历顺序之后的那个节点,把所有原本为空的左子节点都指向了中序遍历之前的那个节点
# 此处只给出中序遍历,前序遍历只需修改输出顺序即可# 而后序遍历,由于遍历是从根开始的,而线索二叉树是将为空的左右子节点连接到相应的顺序上,使其能够按照相应准则输出# 但是后序遍历的根节点却已经没有额外的空间来标记自己下一个应该访问的节点,# 所以这里需要建立一个临时节点dump,令其左孩子是root。并且还需要一个子过程,就是倒序输出某两个节点之间路径上的各个节点。
# 莫里斯遍历,借助线索二叉树中序遍历(附前序遍历)class Solution: def inOrd(self, root: TreeNode) -> List[int]: res = [] # cur = pre = TreeNode(None) cur = root
while cur: if not cur.left: res.append(cur.val) # print(cur.val) cur = cur.right else: pre = cur.left while pre.right and pre.right != cur: pre = pre.right if not pre.right: # print(cur.val) 这里是前序遍历的代码,前序与中序的唯一差别 pre.right = cur cur = cur.left else: pre.right = None res.append(cur.val) # print(cur.val) cur = cur.right return res

# N叉树遍历# 时间复杂度:时间复杂度:O(M),其中 M 是 N 叉树中的节点个数。每个节点只会入栈和出栈各一次。# 空间复杂度:O(M)。在最坏的情况下,这棵 N 叉树只有 2 层,所有第 2 层的节点都是根节点的孩子。# 将根节点推出栈后,需要将这些节点都放入栈,共有 M−1个节点,因此栈的大小为 O(M)。

# N叉树简洁递归class Solution: def preorder(self, root: 'Node') -> List[int]: if not root: return [] res = [root.val] for node in root.children: res.extend(self.preorder(node)) return res
# N叉树通用递归模板class Solution: def preorder(self, root: 'Node') -> List[int]: res = [] def helper(root): if not root: return res.append(root.val) for child in root.children: helper(child) helper(root) return res
# N叉树迭代方法class Solution: def preorder(self, root: 'Node') -> List[int]: if not root: return [] s = [root] # s.append(root) res = [] while s: node = s.pop() res.append(node.val) # for child in node.children[::-1]: # s.append(child) s.extend(node.children[::-1]) return res


breadth first


    
    
    
    
    
# 「**无向图的遍历**」 q = collections.deque([i]) while q: cur = q.popleft() for nxt in dt[cur]: if not vst[nxt]: vstd[nxt] = True q.append(nxt)


# 「**二叉树层序遍历**」q = deque([root])res = []while q :    l = []    for i in range(len(q)) :        t = q.popleft()        l.append(t.val)        if t.left : q.append(t.left)        if t.right : q.append(t.right)    res.append(l)return res

图论


  
  
  
  
  
#「Dijkstra最短路径」dic = collections.defaultdict(list)for u, v, w in edges:    dic[u].append([v, w])    dic[v].append([u, w])q = [(0, n)]dist = [-1] * (n + 1)while q:    dis, cur = heapq.heappop(q)    if dist[cur] < 0:        dist[cur] = dis        for nxt, wi in dic[cur]:            heapq.heappush(q, [dis + wi, nxt])


"Floyd finds the path in the picture"


# Floyd算法 求图中任意2点距离ds = defaultdict(int)st = set()for i, (x, y) in enumerate(ess):    ds[(x, y)] = vs[i]    ds[(y, x)] = 1 / vs[i]    st.update({x,y})arr = list(st)for k in arr:    for i in arr:        for j in arr:            if ds[(i, k)] and ds[(k, j)]:                ds[(i, j)] = ds[(i, k)] * ds[(k, j)]
¤Expand  reading¤ 

3DXR technology  |  terminal technology  |  audio and video technology

Server-side technology  |  Technical quality  |  Data algorithm


This article is shared from the WeChat public account - Big Taobao Technology (AlibabaMTT).
If there is any infringement, please contact [email protected] for deletion.
This article participates in the " OSC Source Creation Plan ". You who are reading are welcome to join and share together.

A programmer born in the 1990s developed a video porting software and made over 7 million in less than a year. The ending was very punishing! High school students create their own open source programming language as a coming-of-age ceremony - sharp comments from netizens: Relying on RustDesk due to rampant fraud, domestic service Taobao (taobao.com) suspended domestic services and restarted web version optimization work Java 17 is the most commonly used Java LTS version Windows 10 market share Reaching 70%, Windows 11 continues to decline Open Source Daily | Google supports Hongmeng to take over; open source Rabbit R1; Android phones supported by Docker; Microsoft's anxiety and ambition; Haier Electric shuts down the open platform Apple releases M4 chip Google deletes Android universal kernel (ACK ) Support for RISC-V architecture Yunfeng resigned from Alibaba and plans to produce independent games on the Windows platform in the future
{{o.name}}
{{m.name}}

Guess you like

Origin my.oschina.net/u/4662964/blog/11104136