【LeetCode 刷题】二叉树-二叉树的属性

此博客为《代码随想录》二叉树章节的学习笔记,主要内容为二叉树的属性相关的题目解析。

文章目录

101. 对称二叉树

题目链接

python 复制代码
class Solution:
    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        def traversal(L, R):
            if not L and not R:
                return True
            if not L or not R or L.val != R.val:
                return False
            return traversal(L.left, R.right) and traversal(L.right, R.left)
        
        return not root or traversal(root.left, root.right)
  • 递归时,需要判断 L 和 R 两个节点,因此不能直接使用题目所给的函数(只有一个参数),而需另外创建 traversal(L, R)
  • 分别递归 (L.left, R.right) 和 (L.right, R.left)

104.二叉树的最大深度

题目链接

python 复制代码
class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0
        return max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1
  • 深度优先遍历算法:后序遍历,因为需要先得到左、右子树的深度,才能够得到当前节点的深度;不用创建新的递归函数
  • 广度优先遍历算法:见博客

111.二叉树的最小深度

题目链接

python 复制代码
class Solution:
    def minDepth(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0
        if not root.left:
            return self.minDepth(root.right) + 1
        if not root.right:
            return self.minDepth(root.left) + 1
        return min(self.minDepth(root.left), self.minDepth(root.right)) + 1
  • 深度优先遍历算法:后序遍历,但与上题不同,不能简单返回左右子树的 min,而需要特判左、右子树为空的情况;不用创建新的递归函数
  • 广度优先遍历算法:见博客

222.完全二叉树的节点个数

题目链接

python 复制代码
class Solution:
    def countNodes(self, root: Optional[TreeNode]) -> int:
        if root is None:
            return 0

        # 判断当前以当前节点为根结点的子树是否为满二叉树
        leftHeight, rightHeight = 0, 0
        leftPtr, rightPtr = root.left, root.right
        while leftPtr:
            leftPtr = leftPtr.left
            leftHeight += 1
        while rightPtr:
            rightPtr = rightPtr.right
            rightHeight += 1
        
        if leftHeight == rightHeight:
            return pow(2, leftHeight + 1) - 1
        return self.countNodes(root.left) + self.countNodes(root.right) + 1
  • 满二叉树节点数计算公式: 2 h − 1 2^{h}-1 2h−1
  • 判断是否为满二叉树的方式:左指针一直向左指,右指针一直向右指,如果两侧深度一样,则为满二叉树

110.平衡二叉树

题目链接

python 复制代码
class Solution:
    def isBalanced(self, root: Optional[TreeNode]) -> bool:
        def traversal(node: Optional[TreeNode]) -> int:
            if node is None:
                return 0
            left = traversal(node.left)
            if left == -1:
                return -1
            right = traversal(node.right)
            if right == -1:
                return -1
            if abs(left - right) <= 1:
                return max(left, right) + 1
            else:
                return -1
                
        return traversal(root) != -1
  • 后序遍历+剪枝,剪枝操作通过特定的函数返回值来实现
  • 如果左右子树高度差已经超过 1,则函数返回 -1;否则,正常返回子树高度

257. 二叉树的所有路径

题目链接

python 复制代码
class Solution:
    def binaryTreePaths(self, root: Optional[TreeNode]) -> List[str]:
        path, res = [], []

        def traversal(node: Optional[TreeNode]) -> None:
            if node is None:
                return
            path.append(str(node.val))
            if not node.left and not node.right:
                res.append('->'.join(path))
            else:
                traversal(node.left)
                traversal(node.right)
            path.pop()
        
        traversal(root)
        return res
  • 先序遍历,先把当前节点放入 path,之后递归处理左右节点
  • 不能在 if node is None: 判断内部收集答案(会重复收集),而应该在叶子节点的位置收集

404.左叶子之和

题目链接

python 复制代码
class Solution:
    def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
        res = 0

        def traversal(node: Optional[TreeNode]):
            nonlocal res
            if node is None:
                return
            if node.left and not node.left.left and not node.left.right:
                res += node.left.val
            traversal(node.left)
            traversal(node.right)
        
        traversal(root)
        return res
  • 判断左叶子的逻辑需要在左叶子结点的上一层
  • nonlocal 表示外部嵌套函数内的局部变量变量

513.找树左下角的值

题目链接

python 复制代码
class Solution:
    def findBottomLeftValue(self, root: Optional[TreeNode]) -> int:
        maxDepth, res = 0, 0
        
        def traversal(node: Optional[TreeNode], depth: int):
            nonlocal maxDepth, res
            if node is None:
                return
            traversal(node.left, depth + 1)
            if depth > maxDepth:
                maxDepth = depth
                res = node.val
            traversal(node.right, depth + 1)
        
        traversal(root, 1)
        return res
  • 深度优先遍历:中序或后序遍历均可(要保证第一个访问的是"左"),之后正常遍历整棵树,并记录目前最大深度;左下角节点肯定为第一个到达最大深度的节点
  • 层序遍历:遍历到最后一层找最左侧节点(更直观)

112. 路径总和

题目链接

python 复制代码
class Solution:
    def hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        if root is None:
            return False
        targetSum -= root.val
        if not root.left and not root.right:
            return targetSum == 0
        return self.hasPathSum(root.left, targetSum) or self.hasPathSum(root.right, targetSum)
  • 到达叶节点时,判断 targetSum == 0
相关推荐
打工仔折腾 AI2 分钟前
用UU远程把家里电脑变成AI Agent常驻服务器:CLI、端口映射与代理实测
运维·服务器·人工智能·后端·python·电脑·ai agent 实战
泡海椒19 分钟前
JQuick-Excel dateFormat 转换实战:日期值与 FORMAT 显示格式的边界
开发语言·python·excel
念越23 分钟前
接口自动化测试从入门到实战:接口用例设计、Requests、Pytest、YAML、JSON Schema 与 Allure 报告
python·测试工具·自动化·json·pytest
言乐627 分钟前
Python贪心算法实现搜索推荐
python·django·virtualenv·pygame·tornado
50万马克的面包28 分钟前
顺序表和链表_精华知识点_CSDN博客
数据结构·链表
benchmark_cc32 分钟前
A股量化尾盘筛选对数据时效敏感:行情链路变慢时先排查哪里?
python·数据分析·pandas·量化交易·股票数据·quantdash
All for pursuit.33 分钟前
【回溯-7】494.目标和
数据结构·c++·算法·leetcode
白杨尚青34 分钟前
C++入门篇(十三):vector(上)——动态数组:构造、空间增长与迭代器失效
开发语言·c++·笔记·算法·stl
Jasmine_llq35 分钟前
《P17461 [GESP202609 八级] 生成树计数》
算法·栈·tarjan 算法·边双连通分量·深度优先搜索 dfs·tarjan 保存当前路径节点·模乘法
Jasmine_llq37 分钟前
《P17462 [GESP202609 八级] 末班车》
算法·dijkstra 算法·最大化版本,求最长可行值·建反向图(逆图 / 反转边)·多源 dijkstra 思想·对每个终点单独跑一遍djst·离线预处理 + 在线查询