代码随想录27期|Python|Day16|二叉树|104.二叉树的最大深度|111.二叉树的最小深度|222.完全二叉树的节点个数

二叉树专题,重点掌握后续的递归和中间节点的处理。

104. 二叉树的最大深度 - 力扣(LeetCode)

本题在前一章已经解决了层序遍历的解法,现在来聊一下递归法。

首先需要明确两个概念:深度和高度。(注意,起始位置的值都是1)

深度:从root开始,到当前位置所在节点的层数;

高度:从底层叶子节点开始,到当前所在节点的层数。

再来说一下选择什么顺序来遍历。

前序:从root出发,直接找的是深度;

后序:从叶子节点出发,返回给root节点高度。

也就是说,不管选择哪一种,中间节点都是单独处理的

后序遍历

按照递归的书写三部曲,可以写出后序遍历的方法。

python 复制代码
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        # 后序遍历(Version 1)
        # step1 确定返回值类型:TreeNode
        # step2 确定终止条件:当前节点是空
        if not root:
            return 0
        else:
        # step3 单层处理:按照"左右中"的顺序,先遍历左节点高度,再遍历右节点高度,汇总到中间节点取较大值,再加1(因为当前中间节点也算作一层)
            left_height = self.maxDepth(root.left)
            right_height = self.maxDepth(root.right)
        return max(left_height, right_height) + 1

        # 精简递归(Version 2)
        return 0 if not root else max(self.maxDepth(root.left), self.maxDepth(root.right)) + 1

前序遍历

要麻烦很多,还涉及到回溯算法 ,十分甚至九分的不推荐

python 复制代码
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        # 递归(前序遍历)
        res = 0
        if not root:
            return 0
        self.getdepth(root, 1)
        return res

    def getdepth(self, node, depth):
        res = max(depth, res)
        if node.left == None and node.right == None:
            return
        if node.left:
            depth += 1
            self.getdepth(node.left, depth)
            depth -= 1  # 回溯算法
        if node.right:
            depth += 1
            self.getdepth(node.right, depth)
            depth -= 1
        return

559. N 叉树的最大深度 - 力扣(LeetCode)

和上面相似的一道题,只用了递归+左右中的后序遍历。

只需要用for遍历所有孩子节点(其实就是上面分别判断左节点和右节点的推广)。

python 复制代码
"""
# Definition for a Node.
class Node(object):
    def __init__(self, val=None, children=None):
        self.val = val
        self.children = children
"""

class Solution(object):
    def maxDepth(self, root):
        """
        :type root: Node
        :rtype: int
        """
        if not root:
            return 0

        max_depth = 1  # 在排除顶部节点是空的时候初始化最大值是1
        
        # 遍历所有的孩子节点
        for child in root.children:
            # 注意在每次比较的时候+ 1,表示计算上了中间节点
            max_depth = max(self.maxDepth(child) + 1, max_depth)
        
        return max_depth

111. 二叉树的最小深度 - 力扣(LeetCode)

本题需要注意的是和上面求解最大值需要遍历到底不一样,本题需要遍历到第一个叶子节点,也就是左右子树都没有的第一个节点。

依然使用后序遍历

递归法

python 复制代码
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def minDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        # 递归法
        if not root:
            return 0
        else:
            # 左
            left_height = self.minDepth(root.left)
            # 右
            right_height = self.minDepth(root.right)
            # 中
            if root.left and root.right == None:  # 左子树存在,右子树不存在
                return left_height + 1
            if root.right and root.left == None:  # 右子树存在左子树不存在
                return right_height + 1
        # 遇到叶子节点返回到中间节点的最小值
        return min(left_height, right_height) + 1

精简递归

把求解左右高度的简化到中间处理的返回值处。

python 复制代码
            # 左
            left_height = self.minDepth(root.left)
            # 右
            right_height = self.minDepth(root.right)

222. 完全二叉树的节点个数 - 力扣(LeetCode)

递归(后序遍历)

python 复制代码
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def countNodes(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        # 当作普通二叉树
        if not root:
            return 0
        # 左
        left_num = self.countNodes(root.left)
        # 右
        right_num = self.countNodes(root.right)
        # 中
        return left_num + right_num + 1

        # 精简版
        if not root:
            return 0
        return self.countNodes(root.left) + self.countNodes(root.right) + 1

利用完全二叉树递归

题干当中还特别说明了是完全二叉树,所以我们可以使用完全二叉树在左右外侧深度相等的时候是满二叉树的性质来统计。

简单概括就是:如果这一层的左子树的左深度和右子树的右深度相等,那么就可以判断现在这是满二叉树。

利用这个性质,我们就很容易可以判断满足满二叉树的条件。

python 复制代码
# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def countNodes(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        # 利用完全二叉树
        if not root:
            return 0

        # 判断是满二叉树直接输出
        leftnode = root.left
        rightnode = root.right
        left_depth, right_depth = 0, 0
        while leftnode:
            leftnode = leftnode.left
            left_depth += 1
        while rightnode:
            rightnode = rightnode.right
            right_depth += 1
        if left_depth == right_depth:
            return (2 << left_depth) - 1  # 2 << 1 = 2 ^ 2
        
        # 普通二叉树正常递归输出
        return self.countNodes(root.left) + self.countNodes(root.right) + 1

第16天完结🎉

相关推荐
z千鑫2 分钟前
【人工智能】深入理解PyTorch:从0开始完整教程!全文注解
人工智能·pytorch·python·gpt·深度学习·ai编程
流星白龙18 分钟前
【C++习题】10.反转字符串中的单词 lll
开发语言·c++
尘浮生25 分钟前
Java项目实战II基于微信小程序的校运会管理系统(开发文档+数据库+源码)
java·开发语言·数据库·微信小程序·小程序·maven·intellij-idea
MessiGo26 分钟前
Python 爬虫 (1)基础 | 基础操作
开发语言·python
Tech Synapse31 分钟前
Java根据前端返回的字段名进行查询数据的方法
java·开发语言·后端
乌啼霜满天24940 分钟前
JDBC编程---Java
java·开发语言·sql
肥猪猪爸1 小时前
使用卡尔曼滤波器估计pybullet中的机器人位置
数据结构·人工智能·python·算法·机器人·卡尔曼滤波·pybullet
色空大师1 小时前
23种设计模式
java·开发语言·设计模式
Bruce小鬼1 小时前
QT文件基本操作
开发语言·qt
2202_754421541 小时前
生成MPSOC以及ZYNQ的启动文件BOOT.BIN的小软件
java·linux·开发语言