当前位置:   article > 正文

【力扣hot100】刷题笔记Day11

【力扣hot100】刷题笔记Day11

前言

  • 科研不顺啊......又不想搞了,随便弄弄吧,多花点时间刷题,今天开启二叉树!

94. 二叉树的中序遍历 - 力扣(LeetCode)

  • 递归

      1. # 最简单递归
      2. class Solution:
      3. def inorderTraversal(self, root: TreeNode) -> List[int]:
      4. if not root:
      5. return []
      6. return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)
      7. # 前/后序就换一下顺序
      8. # 通用模板
      9. class Solution:
      10. def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
      11. res = [] # 收集结果
      12. def dfs(root):
      13. if not root: # 访问到空结点直接返回
      14. return
      15. # 前后序就以下换成对应顺序
      16. dfs(root.left) # 左
      17. res.append(root.val) # 中
      18. dfs(root.right) # 右
      19. dfs(root)
      20. return res
  • 迭代

    • 图和代码参考王尼玛题解
      1. class Solution:
      2. def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
      3. res = []
      4. stack = []
      5. while stack or root:
      6. # 不断往左子树方向走,每走一次就将当前节点保存到栈中
      7. # 这是模拟递归的调用
      8. while root:
      9. # res.append(root.val) # 前/后序改到这
      10. stack.append(root)
      11. root = root.left # 后序改成right
      12. # 当前节点为空,说明左边走到头了,从栈中弹出节点并保存
      13. # 然后转向右边节点,继续上面整个过程
      14. temp = stack.pop()
      15. res.append(temp.val) # 前/后序删掉
      16. root = temp.right # 后序改成left
      17. return res # 后序的话就是[中右左]反过来,return res[::-1]
  •  Morris遍历

    • 过程看官解的动图
    • cur无左孩子,说明到最左端:
      • 加入结果,cur右移
    • cur有左孩子,说明有前驱,找前驱
      • 前驱无右孩:生成链接、cur左移
      • 前驱有右孩:断开连接,记录cur结果,cur右移
      1. class Solution:
      2. def inorderTraversal(self, root: TreeNode) -> List[int]:
      3. res = []
      4. cur, prev = root, None
      5. while cur:
      6. if not cur.left: # 无左孩,到最左端
      7. res.append(cur.val) # 将当前节点cur的值加入结果列表
      8. cur = cur.right # 将当前节点指向右子树
      9. else:
      10. prev = cur.left # 找到当前节点cur的左子树的最右节点(前驱)
      11. while prev.right and prev.right != cur:
      12. prev = prev.right
      13. if not prev.right: # 前驱无右孩
      14. prev.right = cur # 添加连接
      15. # res.append(cur.val) # 如果是前序,下面的加入结果改到这
      16. cur = cur.left # 左移
      17. else: # 前驱有右孩
      18. prev.right = None # 断开连接
      19. res.append(cur.val) # 将当前节点cur的值加入结果列表
      20. cur = cur.right # 右移
      21. return res
  •  标记迭代

      1. class Solution:
      2. def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
      3. res = []
      4. stack = [(0, root)] # 0表示当前未访问,1表示已访问
      5. while stack:
      6. flag, cur = stack.pop()
      7. if not cur: continue
      8. if flag == 0:
      9. stack.append((0, cur.right)) # 右
      10. stack.append((1, cur)) # 中
      11. stack.append((0, cur.left)) # 左
      12. else:
      13. res.append(cur.val)
      14. return res

二叉树所有遍历模板总结

144. 二叉树的前序遍历 - 力扣(LeetCode)

145. 二叉树的后序遍历 - 力扣(LeetCode)

102. 二叉树的层序遍历 - 力扣(LeetCode)

  • 两个列表

      1. class Solution:
      2. def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
      3. if not root:
      4. return []
      5. cur, res = [root], [] # cur表示当前层未访问结点,res为结果
      6. while cur:
      7. lay, layval = [], [] # lay表示下一层该访问结点,layval表示当前层的数值列表
      8. for node in cur: # 遍历当前层所有结点
      9. layval.append(node.val)
      10. if node.left: lay.append(node.left) # 添加左结点到下一层
      11. if node.right: lay.append(node.right) # 添加右结点到下一层
      12. cur = lay # 更新下一层
      13. res.append(layval) # 更新结果集
      14. return res
  • 队列BFS

      1. """
      2. # BFS模板
      3. while queue 不空:
      4. cur = queue.pop()
      5. for 节点 in cur的所有相邻节点:
      6. if 该节点有效且未访问过:
      7. queue.push(该节点)
      8. """
      9. class Solution:
      10. def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
      11. if not root:
      12. return []
      13. res = [] # 结果
      14. q = deque() # 队列
      15. q.append(root)
      16. # q = deque([root]) # 直接赋值需要传入可迭代对象[]
      17. while q:
      18. vals = [] # 存当前层的值
      19. for i in range(len(q)): # 遍历队列中(当前层)所有结点
      20. cur = q.popleft()
      21. vals.append(cur.val)
      22. if cur.left: q.append(cur.left)
      23. if cur.right: q.append(cur.right)
      24. res.append(vals)
      25. return res
  •  DFS递归

      1. class Solution:
      2. def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
      3. res = []
      4. self.level(root, 0, res)
      5. return res
      6. def level(self, root: Optional[TreeNode], level: int, res: List[List[int]]):
      7. if not root: return
      8. if len(res) == level: res.append([]) # 一直向左遍历,新增层数对应的结果列表
      9. res[level].append(root.val) # 当前结点加入当前层的结果里去
      10. if root.left: self.level(root.left, level+1, res) # 递归遍历左子树
      11. if root.right: self.level(root.right, level+1, res) # 递归遍历右子树

589. N 叉树的前序遍历 - 力扣(LeetCode)

  • 递归

      1. # 简单递归
      2. class Solution:
      3. def preorder(self, root: 'Node') -> List[int]:
      4. if not root: return
      5. temp = []
      6. for child in root.children:
      7. temp += self.preorder(child)
      8. return [root.val] + temp
      9. # 常规递归
      10. class Solution:
      11. def preorder(self, root: 'Node') -> List[int]:
      12. res = []
      13. def dfs(cur):
      14. if not cur: return
      15. res.append(cur.val)
      16. for child in cur.children: # 遍历每一个子结点
      17. dfs(child)
      18. dfs(root)
      19. return res
  • 迭代

      1. class Solution:
      2. def preorder(self, root: 'Node') -> List[int]:
      3. if not root: return
      4. res = []
      5. s = [root]
      6. while s:
      7. cur = s.pop()
      8. res.append(cur.val)
      9. for child in cur.children[::-1]: # 从右往左添加进栈
      10. s.append(child)
      11. # s.extend(cur.children[::-1]) # 也可以直接拼接
      12. return res

590. N 叉树的后序遍历 - 力扣(LeetCode)

后言

  • 今天把以上几个二叉树遍历的题目模板刷熟!这样后面的题才能信手拈来~
本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/194512?site
推荐阅读
相关标签
  

闽ICP备14008679号