【力扣hot100】刷题笔记Day11
前言
- 科研不顺啊......又不想搞了,随便弄弄吧,多花点时间刷题,今天开启二叉树!
94. 二叉树的中序遍历 - 力扣(LeetCode)
-
递归
-
# 最简单递归
class Solution:def inorderTraversal(self, root: TreeNode) -> List[int]:if not root:return []return self.inorderTraversal(root.left) + [root.val] + self.inorderTraversal(root.right)# 前/后序就换一下顺序# 通用模板
class Solution:def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:res = [] # 收集结果def dfs(root):if not root: # 访问到空结点直接返回return# 前后序就以下换成对应顺序dfs(root.left) # 左res.append(root.val) # 中dfs(root.right) # 右dfs(root)return res
-
迭代
- 图和代码参考王尼玛题解
-
class Solution:def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:res = []stack = []while stack or root:# 不断往左子树方向走,每走一次就将当前节点保存到栈中# 这是模拟递归的调用while root:# res.append(root.val) # 前/后序改到这stack.append(root)root = root.left # 后序改成right# 当前节点为空,说明左边走到头了,从栈中弹出节点并保存# 然后转向右边节点,继续上面整个过程temp = stack.pop()res.append(temp.val) # 前/后序删掉root = temp.right # 后序改成leftreturn res # 后序的话就是[中右左]反过来,return res[::-1]
-
Morris遍历
- 过程看官解的动图
- cur无左孩子,说明到最左端:
- cur有左孩子,说明有前驱,找前驱
- 前驱无右孩:生成链接、cur左移
- 前驱有右孩:断开连接,记录cur结果,cur右移
-
class Solution:def inorderTraversal(self, root: TreeNode) -> List[int]:res = []cur, prev = root, Nonewhile cur:if not cur.left: # 无左孩,到最左端res.append(cur.val) # 将当前节点cur的值加入结果列表cur = cur.right # 将当前节点指向右子树else:prev = cur.left # 找到当前节点cur的左子树的最右节点(前驱)while prev.right and prev.right != cur:prev = prev.rightif not prev.right: # 前驱无右孩prev.right = cur # 添加连接# res.append(cur.val) # 如果是前序,下面的加入结果改到这cur = cur.left # 左移else: # 前驱有右孩prev.right = None # 断开连接res.append(cur.val) # 将当前节点cur的值加入结果列表cur = cur.right # 右移return res
-
标记迭代
-
class Solution:def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:res = []stack = [(0, root)] # 0表示当前未访问,1表示已访问while stack:flag, cur = stack.pop()if not cur: continueif flag == 0:stack.append((0, cur.right)) # 右stack.append((1, cur)) # 中stack.append((0, cur.left)) # 左else:res.append(cur.val)return res
二叉树所有遍历模板总结
144. 二叉树的前序遍历 - 力扣(LeetCode)
145. 二叉树的后序遍历 - 力扣(LeetCode)
102. 二叉树的层序遍历 - 力扣(LeetCode)
-
两个列表
-
class Solution:def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:if not root:return []cur, res = [root], [] # cur表示当前层未访问结点,res为结果while cur:lay, layval = [], [] # lay表示下一层该访问结点,layval表示当前层的数值列表for node in cur: # 遍历当前层所有结点layval.append(node.val)if node.left: lay.append(node.left) # 添加左结点到下一层if node.right: lay.append(node.right) # 添加右结点到下一层cur = lay # 更新下一层res.append(layval) # 更新结果集return res
-
队列BFS
-
"""
# BFS模板
while queue 不空:cur = queue.pop()for 节点 in cur的所有相邻节点:if 该节点有效且未访问过:queue.push(该节点)
"""
class Solution:def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:if not root:return []res = [] # 结果q = deque() # 队列q.append(root)# q = deque([root]) # 直接赋值需要传入可迭代对象[]while q:vals = [] # 存当前层的值for i in range(len(q)): # 遍历队列中(当前层)所有结点cur = q.popleft()vals.append(cur.val)if cur.left: q.append(cur.left)if cur.right: q.append(cur.right)res.append(vals)return res
-
DFS递归
-
class Solution:def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:res = []self.level(root, 0, res)return resdef level(self, root: Optional[TreeNode], level: int, res: List[List[int]]):if not root: returnif len(res) == level: res.append([]) # 一直向左遍历,新增层数对应的结果列表res[level].append(root.val) # 当前结点加入当前层的结果里去if root.left: self.level(root.left, level+1, res) # 递归遍历左子树if root.right: self.level(root.right, level+1, res) # 递归遍历右子树
589. N 叉树的前序遍历 - 力扣(LeetCode)
-
递归
-
# 简单递归
class Solution:def preorder(self, root: 'Node') -> List[int]:if not root: returntemp = []for child in root.children:temp += self.preorder(child)return [root.val] + temp
# 常规递归
class Solution:def preorder(self, root: 'Node') -> List[int]:res = []def dfs(cur):if not cur: returnres.append(cur.val)for child in cur.children: # 遍历每一个子结点dfs(child)dfs(root)return res
-
迭代
590. N 叉树的后序遍历 - 力扣(LeetCode)
后言
- 今天把以上几个二叉树遍历的题目模板刷熟!这样后面的题才能信手拈来~
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/487780.html
如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!