python coding with ChatGPT 打卡第16天| 二叉树:完全二叉树、平衡二叉树、二叉树的所有路径、左叶子之和

news2024/11/30 2:27:58

相关推荐
python coding with ChatGPT 打卡第12天| 二叉树:理论基础
python coding with ChatGPT 打卡第13天| 二叉树的深度优先遍历
python coding with ChatGPT 打卡第14天| 二叉树的广度优先遍历
python coding with ChatGPT 打卡第15天| 二叉树:翻转二叉树、对称二叉树

文章目录

  • 完全二叉树的节点个数
    • Key Points
    • 相关题目
    • 视频讲解
    • 重点分析
  • 平衡二叉树
    • Key Points
    • 相关题目
    • 视频讲解
    • 重点分析
    • 拓展
  • 二叉树的所有路径
    • 相关题目
    • 视频讲解
    • 重点分析
  • 左叶子之和
    • Key Points
    • 相关题目
    • 视频讲解
    • 重点分析

完全二叉树的节点个数

Key Points

  1. 利用完全二叉树的性质:完全二叉树是一种特殊的二叉树,除了最底层,其它每一层都被完全填满,而且最底层从左到右填入节点。

相关题目

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

视频讲解

理解普通二叉树和完全二叉树的区别

重点分析

首先,我们来思考一下如何递归地解决这个问题,再考虑是否有更高效的方法。

方法一:

def countNodes(root):
    if not root:
        return 0
    count_left = countNodes(root.left)
    count_right = countNodes(root.right)
    return count_left + count_right + 1

方法二:(迭代法遍历节点)

def countNodes(root):
    if not root:
        return 0
    stack_record = [root]
    count = 0
    while stack_record:
        node = stack_record.pop()
        count += 1
        if node.right:
            stack_record.append(node.right)
        if node.left:
            stack_record.append(node.left)

    return count

解决这个问题的关键是利用完全二叉树的性质。
完全二叉树的高度可以通过连续地访问左子树来确定。
在这里插入图片描述

在这里插入图片描述

方法三:
如果左子树的高度等于右子树的高度,则为满二叉树

def get_height(node):
    if not node:
        return 0
    height = 0
    while node:
        node = node.left
        height += 1
    return height

def get_count(height):
    num = 2**height - 1
    return num

def countNodes(root):
    if not root:
        return 0
    left_height = get_height(root.left)
    right_height = get_height(root.right)
    if left_height > right_height:
        right_count = get_count(right_height)
        left_count = countNodes(root.left)
    else:
        left_count = get_count(left_height)
        right_count = countNodes(root.right)
    return 1+left_count+right_count

方法四:
在完全二叉树中,如果递归向左遍历的深度等于递归向右遍历的深度,那说明就是满二叉树。

def countNodes(root):
    if not root:
        return 0
    left = root.left
    right = root.right
    left_height = 1
    right_height = 1
    while left:
        left_height += 1
        left = left.left
    while right:
        right_height += 1
        right = right.right
    if left_height == right_height:
        return get_count(left_height)
    return countNodes(root.left) + countNodes(root.right) + 1
class Solution: # 利用完全二叉树特性
    def countNodes(self, root: TreeNode) -> int:
        if not root: return 0
        count = 1
        left = root.left; right = root.right
        while left and right:
            count += 1
            left = left.left; right = right.right
        if not left and not right: # 如果同时到底说明是满二叉树,反之则不是
            return 2**count-1
        return 1 + self.countNodes(root.left) + self.countNodes(root.right)

平衡二叉树

Key Points

判断一个二叉树是否是高度平衡的,其定义是:一个二叉树每个节点的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是高度平衡的二叉树。

相关题目

110. 平衡二叉树

视频讲解

后序遍历求高度

重点分析

在这里插入图片描述

def isBalanced(root):
    if not root:
        return True

    height = get_height(root)
    if height == -1:
        return False
    return True

def get_height(node):
    if not node:
        return 0
    left_height = get_height(node.left)
    right_height = get_height(node.right)

    if left_height == -1 or right_height == -1:
        return -1

    if abs(left_height - right_height) > 1:
        return -1
    return 1 + max(left_height, right_height)

这种方法的好处是它在计算高度的同时检查平衡性,只需遍历树一次,提高了效率。

拓展

在这里插入图片描述

二叉树的所有路径

相关题目

257. 二叉树的所有路径

视频讲解

递归中带着回溯

重点分析

方法一:
递归法

在这里插入图片描述

class Solution:
    def binaryTreePaths(self, root: TreeNode) -> [str]:
        if not root:
            return []
        paths = []
        self._findPaths(root, "", paths)
        return paths
    
    def _findPaths(self, node, path, paths):
        # 更新当前路径
        currentPath = path + str(node.val)
        # 如果是叶子节点,添加路径到结果列表
        if not node.left and not node.right:
            paths.append(currentPath)
        else:
            # 如果不是叶子节点,递归遍历子节点
            if node.left:
                self._findPaths(node.left, currentPath + "->", paths)
            if node.right:
                self._findPaths(node.right, currentPath + "->", paths)

# 示例使用
# 假设我们有一个二叉树,我们可以创建这个树的节点,并调用上述函数
# 比如:
#     1
#    / \
#   2   3
#    \
#     5
# root = TreeNode(1)
# root.left = TreeNode(2)
# root.right = TreeNode(3)
# root.left.right = TreeNode(5)
# solution = Solution()
# print(solution.binaryTreePaths(root))

方法二:
迭代法(更好理解)

在这里插入图片描述

class Solution:
    def binaryTreePaths(self, root: TreeNode) -> [str]:
        if not root:
            return []
        paths = []
        stack = [(root, str(root.val))]  # 初始化栈,包含节点和路径
        
        while stack:
            node, path = stack.pop()  # 取出当前节点和路径
            
            # 如果是叶子节点,添加路径到结果列表
            if not node.left and not node.right:
                paths.append(path)
            else:
                # 如果不是叶子节点,更新路径并将子节点加入栈
                if node.right:
                    stack.append((node.right, path + "->" + str(node.right.val)))
                if node.left:
                    stack.append((node.left, path + "->" + str(node.left.val)))
        
        return paths

在这个迭代版本中,我们使用了一个栈来存储每个节点以及从根节点到该节点的路径。这种方法模拟了递归过程的深度优先搜索(DFS)前序遍历,确保了我们能够访问到每一个叶子节点,并在到达叶子节点时记录完整的路径。

这种迭代方法提供了一种不使用系统调用栈的递归的替代方案,对于深度非常大的树来说,可以避免递归导致的栈溢出问题。

左叶子之和

Key Points

  1. 要注意是判断左叶子,不是二叉树左侧节点
  2. 判断是否是左叶子,需要通过父节点来判断

相关题目

404. 左叶子之和

视频讲解

总有一些规则让你找不到北

重点分析

方法一:
递归法:

def sumOfLeftLeaves(root):
    if not root:
        return 0

    res = 0
    if isLeave(root.left):
        res += root.left.val
        res += sumOfLeftLeaves(root.right)
    else:
        res += sumOfLeftLeaves(root.left) + sumOfLeftLeaves(root.right)
    return res

def isLeave(node):
    if node:
        if not node.left and not node.right:
            return True
    return False

方法二:
迭代法(更好理解)

def sumOfLeftLeaves(root):
    if not root:
        return 0
    stack_record = [root]
    res = 0
    while stack_record:
        node = stack_record.pop()
        if isLeave(node.left):
            res += node.left.val
            if node.right:
                stack_record.append(node.right)
        else:
            if node.right:
                stack_record.append(node.right)
            if node.left:
                stack_record.append(node.left)
    return res

精简版:

def sumOfLeftLeaves(root):
    if not root:
        return 0
    stack_record = [root]
    res = 0
    while stack_record:
        node = stack_record.pop()
        if isLeave(node.left):
            res += node.left.val
        if node.right:
            stack_record.append(node.right)
        if node.left:
            stack_record.append(node.left)

    return res

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1432148.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器翻译后的美赛论文怎么润色

美赛论文的语言表达一直是组委会看重的点,清晰的思路和地道的语言在评审中是重要的加分项。 今天我们就来讲讲美赛论文的语言问题。 我相信有相当一部分队伍在打美赛的时候,出于效率的考量,都会选择先写中文论文,再机翻成英文。 …

海外盲盒系统搭建,加快盲盒企业出海进程

盲盒作为我国的潮流消费模式,融入了潮流、艺术、动漫等多种元素,吸引了使得越来越多的“Z世代”玩家进入到盲盒市场,促进了市场的迅速扩大,同时也吸引了众多企业入场,“盲盒经济”迅速走红。 盲盒走向海外市场 随着盲…

安装配置Oracle 11g 、PLSQL及使用Navicat远程连接Oracle

目录 一、下载 二、安装 1.执行安装程序 2.配置安全更新 3.安装选项 4.系统类 5.网络安装选项 6.选择安装类型 7.选择产品语言 8.选择数据库版本 9.指定安装位置 10.选择配置类型 ​编辑11.指定数据库标识符 12.指定配置选项 13.电子邮箱 14.指定数据库存储…

寒假思维训练day17 C. Equal Frequencies

不知不觉已经过了差不多一个月了,坚持一件事情还是有点收获的,今天更新一道1600的构造。 寒假训练计划day17 摘要: Part1 题意 Part2 题解 (有数学推导,latex形式) Part3 代码 (C版本,有详细注释) Part4 我对构造题…

Linux Zip解压缩命令

Zip 用法 $ zip [-选项] [-b 路径] [-t 日期] [-n 后缀名] [压缩文件列表] [-xi 列表] 默认操作是添加或替换压缩文件列表中的压缩文件条目,压缩文件列表可以包括特殊名称 -,压缩标准输入数据 Zip 是一个创建和管理 zip 文件的压缩工具 Unzip 是一个用…

使用 Python 进行自然语言处理第 3 部分:使用 Python 进行文本预处理

一、说明 文本预处理涉及许多将文本转换为干净格式的任务,以供进一步处理或与机器学习模型一起使用。预处理文本所需的具体步骤取决于具体数据和您手头的自然语言处理任务。 常见的预处理任务包括: 文本规范化——将文本转换为标准表示形式,…

初识C语言·编译与链接

1 翻译环境和运行环境 C语言标准ANSI C 实现C语言代码的时候 一般需要经过两种环境,一是翻译环境,二是运行环境,计算机能识别的是二进制的指令,人写完代码后通过翻译环境,使代码变成计算机能读懂的可执行的机器指令&a…

伦敦金重点知识:控制亏损的方法

在很多人的预期中,伦敦金重点知识肯定是那些涉及市场分析的方法,那些方法能帮助投资者一把抓住交易机会,在市场中建立优势。但笔者要说的是,那些方法固然重要,但笔者认为还有更加重要的,那就是控制亏损。控…

大模型增量预训练新技巧:解决灾难性遗忘

大家好,目前不少开源模型在通用领域具有不错的效果,但由于缺乏领域数据,往往在一些垂直领域中表现不理想,这时就需要增量预训练和微调等方法来提高模型的领域能力。 但在领域数据增量预训练或微调时,很容易出现灾难性…

LLM大模型

LLM 学习链接 : 大语言模型 LLM行业背景和市场需求 大模型的涌现能力 大模型核心前沿 大模型应用范式和职业规划

大数据 - Spark系列《四》- Spark分布式运行原理

Spark系列文章: 大数据 - Spark系列《一》- 从Hadoop到Spark:大数据计算引擎的演进-CSDN博客 大数据 - Spark系列《二》- 关于Spark在Idea中的一些常用配置-CSDN博客 大数据 - Spark系列《三》- 加载各种数据源创建RDD-CSDN博客 目录 🍠…

200行C++代码写一个网络调试助手(TCP服务端TCP客户端)

前言 今天分享一个200行C代码写成的QT网络调试助手。 可以先看看效果 。 因为我不喜欢用QT Designer,因此我用的组件都是使用代码布局的,所以需要设计一下布局。 界面是参考的之前写的串口助手,就是把里面的逻辑改了改,因此外观…

关于网络面试题汇总

什么是TCP/IP五层模型?它们的作用是啥?基于TCP/IP实现的应用(层协议)有哪些? TCP/IP五层模型,从上向下分别是: 应用层:应用程序本身,应用层的作用是负责应用程序之间的…

比特币ETF广告战大爆发!

作者:秦晋 贝莱德主动发起广告攻势。 2月1日,据外媒Cryptoslate报道,贝莱德在提交给美国SEC的一份文件中显示,其提出一项在建筑物侧面投影比特币ETF广告计划。 据介绍,广告内容为:「IBIT」信号是一个以迈阿…

IP风险画像在企业网络安全中应用

随着企业数字化的不断深入,网络安全问题日益突显。IP风险画像作为一种综合性的网络安全工具,为企业提供了更全面的风险评估和防范手段。本文将结合一个实际案例,深入探讨IP风险画像在企业网络安全中的成功应用。 案例背景 一家大型金融机构…

VS2019 添加程序包

dotnet add package AlibabaCloud.SDK.Bailian20230601 来提示添加程序包 选择菜单栏 项目----管理NuGet程序包 输入程序包的名称,然后添加即可, 这只是给当前工程添加,并不是给VS添加,所以你打开新工程,需要使用的话…

详解WebRTC rtc::Thread实现

rtc::Thread介绍 rtc::Thread类不仅仅实现了线程这个执行器(比如posix底层调用pthread相关接口创建线程,管理线程等),还包括消息队列(message_queue)的实现,rtc::Thread启动后就作为一个永不停止的event l…

【图论】基环树

基环树其实并不是树,是指有n个点n条边的图,我们知道n个点n-1条边的连通图是树,再加一条边就会形成一个环,所以基环树中一定有一个环,长下面这样: 由基环树可以引申出基环内向树和基环外向树 基环内向树如…

【开源】WordPress一键崩溃宕机插件(整活娱乐)

插件介绍 可一键实现Wordpress崩溃宕机的整活向插件(请勿用于非法途径,仅供整活娱乐)。鼓励关注网站性能的提升,以提供更好的用户体验,提倡为用户提供良好体验和高效速度的原则。 介绍 长期以来,人们都在…

WordPress从入门到精通【安装部署】

初识WordPress WordPress,简称WP,其简称的由来是取英文单词“word”与“press”的首字母 WP中文官网 1WP主站(英文) 官方标称,已有43%的网站在使用WordPress WordPress亮点 WP使用PHP语言开发,兼容性极…