03.03 二叉树
本次算法题包括
3道二叉树遍历题目1道二叉树还原题目
二叉树定义
# Definition for a binary tree node.
class TreeNode:
def __init__(self, val=0, left=None, right=None):
self.val = val
self.left = left
self.right = right
103. 二叉树的锯齿形层序遍历
解题思路
层序遍历。
设置 bool 变量 leftToRight = True 表示层序遍历每一层遍历方向,初始为从左往右。
层序遍历过程中,将每一层遍历的结果保存到列表 ans 中。
- 若
leftToRight为真,则直接保存; - 若
leftToRight为假,则将层序遍历结果倒叙保存; - 对
leftToRight取非,改变方向。
代码
class Solution:
def zigzagLevelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
if not root:
return []
level = [root]
leftToRight = True # 二叉树层序遍历每一层遍历方向,初始为从左往右
ans = []
while level:
if leftToRight:
ans.append([node.val for node in level])
else:
ans.append([node.val for node in level[::-1]])
# 更新 level
level = [nd for node in level for nd in (node.left, node.right) if nd]
leftToRight = not leftToRight
return ans
124. 二叉树中的最大路径和
解题思路
递归,深度优先搜索(DFS)。
实现 dfs 函数,获取节点 node 对最大路径和的贡献。
- 空节点贡献为
0; - 非空节点贡献为
node.val+ 左右子树贡献的最大值; - 左右子树贡献为负值,则贡献为 0。
最大路径和 ans 等于 node.val + 左子树贡献 + 右子树贡献。
代码
class Solution:
def maxPathSum(self, root: Optional[TreeNode]) -> int:
ans = -float('inf')
def dfs(node):
nonlocal ans
if not node:
return 0
lmax = max(dfs(node.left), 0)
rmax = max(dfs(node.right), 0)
ans = max(ans, node.val + lmax + rmax)
return node.val + max(lmax, rmax)
dfs(root)
return ans
114. 二叉树展开为链表
解题思路
二叉树遍历,本地展开,空间复杂度 O(1)。
遍历过程中,对于当前节点 curr,
- 找到
curr左孩子curr.left的最右节点pre,pre的右孩子指针指向curr.left curr的左孩子赋值为空,右孩子赋值为原来的左孩子curr向右孩子移动
代码
class Solution:
def flatten(self, root: Optional[TreeNode]) -> None:
"""
Do not return anything, modify root in-place instead.
"""
curr = root
while curr:
if curr.left:
pre = nxt = curr.left
while pre.right:
pre = pre.right
pre.right = curr.right
curr.left = None
curr.right = nxt
curr = curr.right
105. 从前序与中序遍历序列构造二叉树
解题思路
递归,深度优先搜索(DFS)。
先序遍历列表 preorder 的第一个元素是根结点值,创建根节点 root = TreeNode(preorder[0])。
从中序遍历列表 inorder 里定位根节点值,下标设为 k,接着通过递归方式创建 root 的左子树和右子树。
k的值表示左子树节点个数是 k 个。inorder 里除了左子树和根节点,剩下的表示右子树。
代码
class Solution:
def buildTree(self, preorder: List[int], inorder: List[int]) -> Optional[TreeNode]:
def dfs(preorder, inorder):
if not preorder:
return None
k = inorder.index(preorder[0])
root = TreeNode(preorder[0])
root.left = dfs(preorder[1:k+1], inorder[:k])
root.right = dfs(preorder[k+1:], inorder[k+1:])
return root
return dfs(preorder, inorder)
参考资料
leetcode-notes/docs/ch03/index.md at main · datawhalechina/leetcode-notes · GitHub