0
点赞
收藏
分享

微信扫一扫

【LeetCode】104 and 543(二叉树问题的解题思路)

二叉树问题的解题思路

⼆叉树题⽬的递归解法可以分两类思路,第⼀类是遍历⼀遍⼆叉树得出答案,第⼆类是通过分解问题计算出答案,这两类思路分别对应着 回溯算法核⼼框架 和 动态规划核⼼框架。下面我将通过题104和543分别进行举例。

104. 二叉树的深度

在这里插入图片描述
解法:深度优先遍历(遍历框架)
该题可以通过遍历二叉树,对每个叶子节点所在深度进行判断,找到二叉树的最大深度。同样明确「要做什么」以及「什么时候做」。前者为当前遍历到的深度变化,后者为遍历到该节点时深度+1,遍历结束回退后深度-1

class Solution:
    res = 0
    depth = 0
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        self.traverse(root)
        return self.res

    def traverse(self, node):
        if not node:
            self.res = max(self.res, self.depth)
            return 
        # 遍历思路求解
        self.depth += 1
        self.traverse(node.left)
        self.traverse(node.right)
        self.depth -= 1

解法2:深度优先遍历(分解问题思路)
该题同样可以用分解问题思路来求解,求以root为根节点的二叉树的最大深度,及分别求得左右子树的最大深度,再对它们之间的最大值+1即为该二叉树的最大深度。具体解法可参考下题。

543. 二叉树的直径

在这里插入图片描述
解法:深度优先遍历(分解问题思路)
对于以root节点为起点的路径,其长度可以等价为其左右子树的最大深度之和。例如对于下图,以2为起点,其路径为2(左子树最大深度)+3(右子树最大深度)等于5。
在这里插入图片描述
所以求以任一节点为起点的路径,可以分解为先求其左子树和右子树的最大深度,再进行求和。
而求解二叉树的直径,要对以其中所有节点为起点的情况进行遍历,找到最长路径。同样,需要明确每个节点「要做什么」以及「什么时候做」,前者为求以其为起点的路径长度。后者为后序遍历,需要先求得其左右子树的最大深度。

# 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
class Solution:
    def diameterOfBinaryTree(self, root: TreeNode) -> int:
        self.result = 0
        def maxDepth(node):
            if not node:
                return 0
            # 分解思路求解,该问题通过遍历一遍二叉树不可以解决,需要从子问题来推导。
            left = maxDepth(node.left)
            right = maxDepth(node.right)
            # print(left, right)
            self.result = max(self.result, left + right)
            return max(left, right) + 1
        maxDepth(root)
        return self.result

总结

综上,遇到⼀道⼆叉树的题⽬时的通⽤思考过程是:
是否可以通过遍历⼀遍⼆叉树得到答案?如果不能的话,是否可以定义⼀个递归函数,通过⼦问题(⼦树)的答案推导出原问题的答案?前者是节点遍历操作,后者是先操作子树,在推导原问题。
后续可以分别用上述两种思路对144. 二叉树的前序遍历进行求解,以此加深理解,体会它们之间的异同点。

举报

相关推荐

0 条评论