好的!我会根据《代码随想录》二叉树相关的第11-21题,逐一为你解析。

这些题目一般涵盖了二叉树的基本操作,比如遍历、深度/宽度优先搜索、最小深度、最大深度、路径等。

我会提供问题的简要描述、解题思路和代码实现,帮助你更好地理解。


11. 二叉树的深度

问题描述:
给定一个二叉树,找出其最大深度。二叉树的深度是指从根节点到最远叶子节点的最长路径上的节点数。

解题思路:

  • 这是一个典型的深度优先搜索(DFS)问题。
  • 从根节点开始递归,左右子树的深度相加,然后加上根节点本身。

代码实现:

# 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

def maxDepth(root: TreeNode) -> int:
    if not root:
        return 0
    # 获取左右子树的深度
    left_depth = maxDepth(root.left)
    right_depth = maxDepth(root.right)
    # 返回左右子树最大深度加1
    return max(left_depth, right_depth) + 1


12. 二叉树的最小深度

问题描述:
给定一个二叉树,找出其最小深度。最小深度是从根节点到最近叶子节点的路径上的节点数。

解题思路:

  • 与最大深度的解法类似,不过我们要注意的是,最小深度应该是在某一侧子树为空时,另一侧子树的深度加上1。
  • 特别注意:当一个子树为空时,另一个子树必须是非空的。

代码实现:

def minDepth(root: TreeNode) -> int:
    if not root:
        return 0
    if not root.left and not root.right:
        return 1
    if not root.left:
        return minDepth(root.right) + 1
    if not root.right:
        return minDepth(root.left) + 1
    return min(minDepth(root.left), minDepth(root.right)) + 1


13. 对称二叉树

问题描述:
判断一个二叉树是否是对称的,即它是否是一个“镜像对称”的二叉树。

解题思路:

  • 二叉树对称意味着左右子树是镜像的,因此我们可以通过递归来判断两棵子树是否镜像相同。
  • 比较两个树节点:节点的值相等并且一个节点的左子树和另一个节点的右子树是镜像的。

代码实现:

def isSymmetric(root: TreeNode) -> bool:
    def isMirror(t1, t2):
        if not t1 and not t2:
            return True
        if not t1 or not t2:
            return False
        return (t1.val == t2.val) and isMirror(t1.left, t2.right) and isMirror(t1.right, t2.left)

    if not root:
        return True
    return isMirror(root.left, root.right)


14. 二叉树的最大路径和

问题描述:
给定一个非空二叉树,返回其最大路径和。路径是从某个节点开始,到任意节点结束的路径,并且路径中至少包含一个节点。

解题思路:

  • 通过深度优先搜索递归每个节点,计算节点作为根节点的最大路径和,并更新全局最大值。
  • 对于每个节点,我们有两个选择:把节点的左子树加到路径中,或者右子树加到路径中。

代码实现:

class Solution:
    def maxPathSum(self, root: TreeNode) -> int:
        self.max_sum = float('-inf')

        def helper(node):
            if not node:
                return 0
            # 递归计算左右子树的最大路径和,若负值则不加
            left = max(helper(node.left), 0)
            right = max(helper(node.right), 0)
            # 更新全局最大路径和
            self.max_sum = max(self.max_sum, node.val + left + right)
            # 返回当前节点作为根节点的最大路径和
            return node.val + max(left, right)

        helper(root)
        return self.max_sum


15. 二叉树的所有路径

问题描述:
给定一个二叉树,返回所有从根节点到叶子节点的路径。

解题思路:

  • 使用深度优先搜索递归遍历二叉树,对于每一个到达叶子的节点,记录路径。

代码实现:

def binaryTreePaths(root: TreeNode):
    def dfs(node, path, paths):
        if node:
            path += str(node.val)
            if not node.left and not node.right:  # 叶子节点
                paths.append(path)
            else:
                path += '->'
                dfs(node.left, path, paths)
                dfs(node.right, path, paths)

    paths = []
    dfs(root, "", paths)
    return paths


16. 填充每个节点的下一个右侧节点指针

问题描述:
给定一个完美二叉树,每个节点都包含有 next 指针,指向其右侧邻居节点。如果没有右侧邻居节点,则 next 指向 null。返回填充好 next 指针的树。

解题思路:

  • 由于是完美二叉树,每一层的节点数量是固定的,因此可以利用层次遍历,一次性填充每一层的 next 指针。

代码实现:

class Solution:
    def connect(self, root: 'Node') -> 'Node':
        if not root:
            return root
        leftmost = root
        while leftmost.left:
            head = leftmost
            while head:
                head.left.next = head.right
                if head.next:
                    head.right.next = head.next.left
                head = head.next
            leftmost = leftmost.left
        return root


17. 二叉搜索树的最近公共祖先

问题描述:
给定一个二叉搜索树,找到两个节点的最近公共祖先。

解题思路:

  • 二叉搜索树的性质:左子树所有节点小于根节点,右子树所有节点大于根节点。
  • 如果两个节点分别位于根节点的左右子树,则根节点就是最近公共祖先。

代码实现:

def lowestCommonAncestor(root: TreeNode, p: TreeNode, q: TreeNode) -> TreeNode:
    while root:
        if p.val < root.val and q.val < root.val:
            root = root.left
        elif p.val > root.val and q.val > root.val:
            root = root.right
        else:
            return root


18. 二叉树的直径

问题描述:
给定一棵二叉树,求其直径。直径是树中任意两个节点之间的最长路径。

解题思路:

  • 直径是通过任意节点的左子树和右子树的最大深度之和来计算的。
  • 使用深度优先搜索进行递归计算每个节点的左右子树深度。

代码实现:

class Solution:
    def diameterOfBinaryTree(self, root: TreeNode) -> int:
        self.diameter = 0

        def depth(node):
            if not node:
                return 0
            left = depth(node.left)
            right = depth(node.right)
            self.diameter = max(self.diameter, left + right)
            return max(left, right) + 1

        depth(root)
        return self.diameter


19. 最大二叉树

问题描述:
给定一个整数数组 nums,根据最大元素值构建一个最大二叉树,返回根节点。

解题思路:

  • 递归的方法,每次找到数组的最大值,作为根节点,然后递归地构建左右子树。

代码实现:

class Solution:
    def constructMaximumBinaryTree(self, nums: List[int]) -> TreeNode:
        if not nums:
            return None
        max_val = max(nums)
        max_index = nums.index(max_val)
        root = TreeNode(max_val)
        root.left = self.constructMaximumBinaryTree(nums[:max_index])
        root.right = self.constructMaximumBinaryTree(nums[max_index + 1:])
        return root


20. 二叉树的层次遍历

问题描述:
给定一个二叉树,返回其节点值的层次遍历。

**解题思路:

**

  • 使用队列进行广度优先搜索(BFS),一层一层地遍历。

代码实现:

from collections import deque

def levelOrder(root: TreeNode):
    if not root:
        return []
    result = []
    queue = deque([root])
    while queue:
        level = []
        for _ in range(len(queue)):
            node = queue.popleft()
            level.append(node.val)
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        result.append(level)
    return result


21. 右视图

问题描述:
从右侧看二叉树,返回从右侧看每一层的节点。

解题思路:

  • 对二叉树进行层次遍历,记录每一层最右侧的节点。

代码实现:

def rightSideView(root: TreeNode):
    if not root:
        return []
    result = []
    queue = deque([root])
    while queue:
        level_size = len(queue)
        for i in range(level_size):
            node = queue.popleft()
            if i == level_size - 1:  # 最右侧的节点
                result.append(node.val)
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
    return result