【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)
  • 递归时,需要判断 LR 两个节点,因此不能直接使用题目所给的函数(只有一个参数),而需另外创建 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
相关推荐
gwf216几秒前
磨损均衡算法(Wear Leveling)——SSD如何让每块闪存“公平退休“?
运维·数据库·人工智能·python·嵌入式硬件·算法·智能硬件
爱吃提升15 分钟前
python 分布式爬虫、爬虫合规与综合实战项目
分布式·爬虫·python
审小匠OpenCPAi16 分钟前
银行流水核查怎么自动化?单边匹配、双向勾稽与图聚类异常检测的工程对比
java·前端·人工智能·python·审计
noipp19 分钟前
推荐题目:洛谷 P6231 [JSOI2013] 公交系统
c语言·数据结构·c++·算法·游戏·洛谷·luogu
c2385633 分钟前
C/C++每日一练6
c语言·c++·算法
AI小码1 小时前
把动作「画」给视频世界模型,跨本体双向推演,李飞飞参与
大数据·人工智能·算法·ai·大模型·音视频·编程
元Y亨H1 小时前
Pandas 解析 Excel 导致的内存溢出(MemoryError)
python·excel
金銀銅鐵2 小时前
[Python] 用 turtle 来绘制瑞典国旗
python
Albert Edison2 小时前
【GUI 自动化测试】Pywinauto 常见操作
自动化测试·python·pywinauto
海兰2 小时前
【高速缓存】RedisVL为文本生成嵌入向量实践指南
人工智能·python·机器学习