代码随想录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天完结🎉

相关推荐
Kisorge23 分钟前
【C语言】指针数组、数组指针、函数指针、指针函数、函数指针数组、回调函数
c语言·开发语言
轻口味1 小时前
命名空间与模块化概述
开发语言·前端·javascript
晓纪同学2 小时前
QT-简单视觉框架代码
开发语言·qt
威桑2 小时前
Qt SizePolicy详解:minimum 与 minimumExpanding 的区别
开发语言·qt·扩张策略
飞飞-躺着更舒服2 小时前
【QT】实现电子飞行显示器(简易版)
开发语言·qt
明月看潮生3 小时前
青少年编程与数学 02-004 Go语言Web编程 16课题、并发编程
开发语言·青少年编程·并发编程·编程与数学·goweb
明月看潮生3 小时前
青少年编程与数学 02-004 Go语言Web编程 17课题、静态文件
开发语言·青少年编程·编程与数学·goweb
Java Fans3 小时前
C# 中串口读取问题及解决方案
开发语言·c#
盛派网络小助手3 小时前
微信 SDK 更新 Sample,NCF 文档和模板更新,更多更新日志,欢迎解锁
开发语言·人工智能·后端·架构·c#
算法小白(真小白)3 小时前
低代码软件搭建自学第二天——构建拖拽功能
python·低代码·pyqt