基础数据结构篇(下)LeetCode 二叉树题目

78 阅读2分钟

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

image.png

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

image.png

114. 二叉树展开为链表

解题思路

二叉树遍历,本地展开,空间复杂度 O(1)。
遍历过程中,对于当前节点 curr

  • 找到 curr 左孩子 curr.left 的最右节点 prepre 的右孩子指针指向 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

image.png

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)

image.png

参考资料

leetcode-notes/docs/ch03/index.md at main · datawhalechina/leetcode-notes · GitHub