代码随想录 Day 15 | 【第六章 二叉树】110.平衡二叉树、257. 二叉树的所有路径、404.左叶子之和、222.完全二叉树的节点个数

具有I2S输出的多模数字麦克风ICS-43434咪头LR引脚接地或电源WS接LRCLK ICS-43434 是一款数字 IS 输出底部收音孔麦克风。完整的 ICS-43434 解决方案包括 MEMS 传感器、信号调理、模数转换器、抽取和抗混叠滤波器、电源管理以及行业标准的 24 位 12S 接口。12S 接口允许 ICS-43434 直接连接到数字处理器,例如 DSP 和微控制器,而无需系统中的音频编解码器。 阅读详情

一、110.平衡二叉树

再一次涉及到,什么是高度,什么是深度,可以巩固一下。

题目链接/文章讲解/视频讲解:代码随想录

1. 整体逻辑

        一棵高度平衡二叉树定义为平衡二叉树 是指该树所有节点的左右子树的高度相差不超过 1。通过比较两两左右子树的高度差是否小于等于1,来判断该树是否是一颗平衡二叉树。

        由于该题是判断高度差,也就是自下而上,所以采用后序遍历,在比较完子树之后将结果传递给父节点,因此必须采用后序遍历。

2. 具体逻辑

(1)终止条件:如果一个节点的子节点是空,那么说明这个节点是叶子节点,而叶子节点的高度是0,所以返回0。

(2)后序遍历:左右中的顺序。

        1)左:利用递归法计算左子树的高度,如果左子树返回值为-1,说明左子树本身不是平衡二叉树,那么也返回一个-1即可。(检查左右子树是否满足平衡二叉树)

        2)右:利用递归法计算右子树的高度,如果右子树返回值为-1,说明右子树本身不是平衡二叉树,那么也返回一个-1即可。(检查左右子树是否满足平衡二叉树)

        3)中:当左右子树均满足平衡二叉树,此时需要对左右子树的高度差进行检查,是否小于等于1,因此定义一个变量来计算左右子树高度差。如果左右子树的高度差小于等于1,那么计算当前父节点的高度,等于取左右子树最大值+1。

(3)最后在主函数调用即可,返回布尔值。

3. 完整代码

class Solution:
    def isBalanced(self, root: Optional[TreeNode])->bool:
        res = self.getHeight(root)
        if res == -1:
            return False
        else:
            return True
    
    def getHeight(self, root: TreeNode)->int:
        if root is None:
            return 0

        # left:
        l_height = self.getHeight(root.left)
        if l_height == -1:
            return -1
        
        # right:
        r_height = self.getHeight(root.right)
        if r_height == -1:
            return -1

        # middle:
        height = abs(r_height - l_height)
        if height > 1:
            return -1
        else:
            return max(l_height, r_height)+1

注意:

        错误思路如下:只判断相邻子树之间如果高度差大于1,则返回false,但平衡二叉树是指该树所有节点的左右子树的高度相差不超过 1,所以必须去计算所有节点的子树高度差均不大于1。

        错误代码将下图这种情况判断为true,而实际上应该判断为false。

        所以正确做法应该是去计算所有节点上左右子树的高度差,再进一步进行判断。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def isBalanced(self, root: Optional[TreeNode]) -> bool:
        if root is None:
            return True
        l_height = self.isBalanced(root.left)
        r_height = self.isBalanced(root.right)
        height = abs(l_height-r_height)
        if height > 1: 
            return False
        else: return True
        

二、257. 二叉树的所有路径

这是大家第一次接触到回溯的过程, 我在视频里重点讲解了 本题为什么要有回溯,已经回溯的过程。

如果对回溯 似懂非懂,没关系, 可以先有个印象。

题目链接/文章讲解/视频讲解:代码随想录

1. 整体逻辑

本题目要求根节点到所有叶子节点的路径,所以从一条路径指向下一条路径会涉及到回溯,将遍历过的路径弹出,继续遍历下一个路径。此外,由于是从根节点出发,所以需要从父节点指向对应的孩子节点,从而寻找路径,所以必须采用前序遍历。

2. 具体逻辑

(1)首先定义一个回溯函数traversal,传入self、cur、path、result。cur用于遍历节点,表示当前父节点;path用于存放遍历过的路径;result用于存放结果集。

(2)前序遍历:中->左->右。

        1)中:将当前父节点的值存放进当前路径中,然后判断是否到达叶子节点(如果当前父节点的左右孩子均为空,那么说明到达了叶子结点,也就是说这条路径遍历完成)。所以需要将这条完整的路径用‘ -> ’ 符号进行连接,并且需要将路径的每个元素转换为str形式,因为最后输出的形式为“List[str]”。接下来将这条路径存放进结果集中,并且返回。

sPath = '->'.join(map(str, path))

        2)接下来进行左遍历:只要当当前父节点左孩子不为空,则一直调用递归函数进行遍历,最后pop出去即可。

        3)最后进行右遍历:同左遍历。

(3)在主函数中,定义一个空数组path和result,判断传入的根结点不为空,然后调用递归函数traversal,最后返回结果。

3. 完整代码

class Solution:
    def traversal(self, cur, path, result):
        # middle:
        path.append(cur.val)
        if cur.left is None and cur.right is None:
            sPath = "->".join(map(str, path))
            result.append(sPath)
            return
        
        # left:
        if cur.left:
            self.traversal(cur.left, path, result)
            path.pop()

        # right:
        if cur.right:
            self.traversal(cur.right, path, result)
            path.pop()

    def binaryTreePaths(self, root):
        result = []
        path = []
        if root is None:
            return result
        self.traversal(root, path, result)
        return result

三、404.左叶子之和

其实本题有点文字游戏,搞清楚什么是左叶子,剩下的就是二叉树的基本操作。

题目链接/文章讲解/视频讲解:代码随想录

1. 整体逻辑

(1)确定判断逻辑:

        左叶子 = 叶子节点(左右孩子均为空)+ 左(父节点的左孩子)

        注意:不可以遍历到叶子节点才进行判断,因为无法知道是否是左孩子,只能知道是叶子节点,所以需要在遍历到父节点就开始对左孩子进行处理。

        如果该节点的左节点不为空,该节点的左节点的左节点为空,该节点的左节点的右节点为空,则找到了一个左叶子,判断代码如下:

if (node->left != NULL && node->left->left == NULL && node->left->right == NULL) {
    左叶子节点处理逻辑
}

(2)选择遍历顺序:

        收集左叶子之和一层层返回给父节点,所以最好使用后序遍历。

2. 具体逻辑

(1)如果遇到节点为空,那么其左叶子之和一定为空,所以返回0。如果遇到叶子节点(左孩子和右孩子为空),叶子节点不是我们要采集的值,因为无法知道是否是左孩子,并且叶子节点收集的是左右子树的和,其左右子树为空,所以返回0。

(2)后序遍历:

        1)左:遍历左子树并收集所有符合左叶子条件的和, 如果该节点的左节点不为空,该节点的左节点的左节点为空,该节点的左节点的右节点为空,则找到了一个左叶子,收集的元素就是该左叶子;

        2)右:同左;

        3)中:左树的左叶子和+右树的左叶子和,并返回左叶子总和。

3. 完整代码

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def sumOfLeftLeaves(self, root: Optional[TreeNode]) -> int:
        if root is None: return 0
        if root.left is None and root.right is None: return 0
        
        # left:
        leftvalue = self.sumOfLeftLeaves(root.left)
        if root.left is not None and root.left.left is None and root.left.right is None:
            leftvalue = root.left.val
        
        # right:
        rightvalue = self.sumOfLeftLeaves(root.right)
        sum = leftvalue + rightvalue
        return sum

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

需要了解,普通二叉树 怎么求,完全二叉树又怎么求

题目链接/文章讲解/视频讲解:代码随想录

1. 整体逻辑

(1)普通二叉树解法:

        遍历左子树的所有节点和右子树的所有节点,两个子树节点相加,再加上根节点1即可。

(2)完全二叉树解法:

        利用完全二叉树特性,终止条件有两个:一是根节点为空,而是左右子树存在满二叉树,则可以使用公式子树节点总数num=(2^层数)-1。

2. 完整代码

(1)普通二叉树解法:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def countNodes(self, root: Optional[TreeNode]) -> int:
        return self.getNodesNum(root)
    def getNodesNum(self, cur):
        if cur is None:
            return 0
        leftnum = self.getNodesNum(cur.left)
        rightnum = self.getNodesNum(cur.right)
        sum = leftnum + rightnum+1
        return sum

(2)完全二叉树解法:

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def countNodes(self, root: Optional[TreeNode]) -> int:
        if root is None: return 0
        left = root.left
        right = root.right
        leftdepth = 0
        rightdepth = 0
        while left:
            left = left.left
            leftdepth += 1
        while right:
            right = right.right
            rightdepth += 1
        if leftdepth == rightdepth:
            return (2<<leftdepth)-1
        return self.countNodes(root.left)+self.countNodes(root.right)+1

短距激光雷达专业讲解:定义、架构、技术路线与选型逻辑 短距激光雷达,通常指有效探测距离不大于 50 米的激光雷达产品。它主要服务于服务机器人、扫地机器人、AGV/AMR、无人机、智能手机、AR/VR、工业安全等中近距感知场景。它与车载中长距激光雷达的最大区别,不是“探测距离短一点”,而是整套工程目标不同。短距激光雷达的核心诉求是:小体积、低成本、高帧率、强抗光、嵌入式集成。单价从百元级扫地机模组,到数千元级工业 3D 雷达不等。一句话概括:中长距车载激光雷达追求远距离、高可靠、车规寿命; 阅读详情

相关推荐

iperf3网络性能测试全攻略:从带宽到丢包率的实战技巧

本文提供了iperf3网络性能测试的完整实战指南,涵盖从基础部署到高级诊断的全流程。详细解析了TCP带宽测试的进阶技巧与UDP丢包率分析的深度方法,帮助网络工程师精准量化带宽、丢包率等关键指标,有效定位网络瓶颈并优化性能。

efc123456的博客 1018

代码随想录 day 15 二叉树

我使用了StringBuilder 但是去回溯的时候处理删除尾部字符,-100 是4个字符,还是应该用List,到收集结果的时候在使用题目要求的格式返回即可。因为题目是求根节点,根节点的最大深度就是最大高度是一样的所以可以用后序遍历)核心是递归终止条件:1.节点是null 返回数量0 2.以当前节点为根节点的树是满二叉树,直接公式计算返回。如果一颗树是完全二叉树,判断是否是满二叉树,那么向左遍历的深度和向右遍历的深度是相等的。参数:当前传入节点。再一次涉及到,什么是高度,什么是深度,可以巩固一下。

weixin_45549711的博客 1127

配电网可靠性评估(一)—最小路法和非序贯蒙特卡洛模拟法的matlab实现

电力系统的可靠性研究是相关领域的热点问题。根据研究对象的不同,又可分为发电系统的可靠性,输电系统的可靠性和配电系统的可靠性。配电网在电力系统中处于最末端的位置,直接和用户相连,一旦出现故障情况,就会在用户侧表现为停电事故。因此对配电网的可靠性评估有着重大意义。......

配电网和matlab的博客 1万+

代码随想录 day15 二叉树 part03

迭代法,大家可以直接过,二刷有精力的时候 再去掌握迭代法。

2401_88561446的博客 497

STM32F4用FSMC驱动AX58100 EtherCAT从站芯片,保姆级配置流程与避坑指南

本文详细介绍了STM32F4通过FSMC接口驱动AX58100 EtherCAT从站芯片的完整配置流程,包括硬件连接、时序优化、协议栈移植及TwinCAT主站集成。针对工业自动化场景,提供高性价比的实时控制解决方案,特别适合机械臂、CNC机床等精确同步应用,并分享关键调试技巧与性能优化方法。

weixin_27869497的博客 306

Ego-Planner实战避坑指南:从环境搭建到仿真运行

本文详细介绍了在Windows系统下,通过WSL2搭建Ego-Planner无人机路径规划算法开发环境的完整流程与实战避坑指南。内容涵盖ROS Noetic安装、第三方依赖库(如Ceres Solver)编译冲突解决、Realsense SDK版本降级处理,以及Gazebo仿真与真机调试的常见问题,旨在帮助开发者高效完成环境配置并成功运行仿真。

weixin_29232507的博客 699

代码随想录算法训练营Day13 | 110.平衡二叉树,404.左叶子之和,222.完全二叉树的节点个数

little__penguin的博客 412

基于verilog的16QAM调制

思路1:正交调幅法——实现16QAM调制,可以理解为时相位相差90度的两个正弦波的4PAM叠加。 4比特输入经过2->4进制转化得到两路2比特输入,然后分别经过4PAM后叠加所得输出即为16QAM调制结果。 具体程序稍后编写。 思路2:复合相移法——可以借助前面编写的QPSK,相当于两路幅度不同的QPSK的叠加,比如幅度分别取1和3 。 思路1正交调幅法的设计方案: 两正弦波相位差...

weixin_30725467的博客 2929

代码随想录 day13:第六章 二叉树 part03

第六章 二叉树 part03110.平衡二叉树 (优先掌握递归)257. 二叉树的所有路径 (优先掌握递归)404.左叶子之和 (优先掌握递归)222.完全二叉树的节点个数(优先掌握递归) 110.平衡二叉树 (优先掌握递归) 再一次涉及到,什么是高度,什么是深度 257. 二叉树的所有路径 (优先掌握递归) 404.左叶子之和 (优先掌握递归) 搞清楚什么是左叶子,剩下的就是二叉树的基本操作。 222.完全二叉树的节点个数(优先掌握递归) 需要了解,普通二叉树 怎么求,完全二叉树又怎么求

z25735的博客 338

YOLO26涨点改进 | 全网首发Conv独家改进篇 | CVPR 2025 | 引入GCConv卷积改进YOLO26,含GCC3k2二次创新,能够捕捉更加丰富和复杂的特征信息,助力高效涨点

本文提出了一种基于GCConv模块的YOLO26目标检测模型改进方案。GCConv模块通过多路径结构增强特征学习能力,在训练阶段采用垂直多卷积和水平多路径配置,推理时重参数化为单一3x3卷积,显著提升推理速度而不损失性能。实验表明,该模块在复杂场景和多尺度目标检测任务中表现优异,特别适合资源受限的实时应用场景。文章详细介绍了GCConv的网络结构、核心代码实现、YAML配置文件修改方法,并提供了两种改进方案(GCConv和GCC3k2)的具体配置指导。

Ai缝合怪、助力小伙伴高效发论文 321

《UDS协议从入门到精通》系列——图解0x34:请求下载

上传下载类服务之0x34-请求下载,图解请求+响应格式,直观易懂,快速上手!!

车载系统攻城狮 4930

算法训练营DAY15 第六章 二叉树part03

递归三部曲1、确定参数返回值,只需要记录路径不需要返回值,参数包括当前节点,记录路径的容器,2、确定终止条件,这里只需要找到叶子节点(左右儿子都为空)就可以运行终止操作,引入一个字符串,记录path中的数以及添加"->"去匹配题目要求的输出格式。3、确定递归单层逻辑,因为是需要寻找所有的路径,当找到叶子节点后还需要返回其根节点,同时path也要删除叶子节点,这个过程就称为回溯。递归三部曲1、确定参数与返回值,参数选为当前节点,返回当前树的高度,若不平衡返回-1;解题思路:不直接操作叶子节点,操作根节点。

2401_89133587的博客 334

Claude Code 分布式并行开发最佳实践:1中枢+10Worker跨多Git仓库全流程落地

本文介绍了一套基于Claude Code和Git Worktree的分布式并行开发方案,解决多仓库、微服务开发中的核心痛点。方案采用"1个决策中枢+10个并行Worker"架构,中枢负责任务拆解和调度,每个Worker绑定独立仓库实现完全隔离开发。关键优势包括:任务并行效率提升10倍、跨仓库依赖自动编排、版本统一管理、零第三方依赖。文章详细提供了环境准备、架构设计、中枢搭建和初始化脚本等全流程落地指南,特别适合多仓库协同的全栈开发场景。

AI天才研究院 244

代码随想录算法训练营DAY15第六章 二叉树part03

【代码】代码随想录算法训练营DAY15第六章 二叉树part03。

2401_88089822的博客 438

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

day15 第六章 二叉树part03

257. 二叉树的所有路径 (优先掌握递归)222.完全二叉树的节点个数(优先掌握递归)110.平衡二叉树 (优先掌握递归)404.左叶子之和 (优先掌握递归)完全二叉树最终可以分解为满二叉树。比较左右子树的高度->

mvufi的博客 263

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

算法跟学Day14【代码随想录】

二叉树的全部遍历方式

qq_37016176的博客 83

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

【数据结构-5】单链表的实现

单链表,具体来说是单向的、不带头的、不循环的链表。链表由一个一个节点组成,每个节点分为数据域和指针域,数据域存放数据,指针域存放下一节点的地址。这样,就可以根据指针域中的地址找到下一个节点,节点就串起来了构成了单链表。

weixin_44218929的博客 187

pandas 深度入门:从数据结构到一份真实销售报表

本文系统讲解Pandas核心应用,从三分钟安装到完整月度报表生成,涵盖数据读取、清洗、筛选、分组聚合、表连接、透视表与时间序列等13个关键环节。强调“先看数据再动手”,掌握Series/DataFrame/Index结构本质,熟练运用loc/iloc、merge校验、agg/transform区别,通过真实案例实现高效报表自动化,告别手动Excel操作。最后提供性能优化与高频报错解决方案,助力读者快速上手,真正实现“写二十行代码,跑三秒出结果”。

信息安全领域优质创作者|操作系统领域专家 282

数据结构的基本概念和算法的初步认识

本文系统阐述数据结构与算法的基础概念,涵盖数据、数据元素、数据对象的层次关系,数据结构的三要素(逻辑结构、存储结构、数据运算),以及抽象数据类型。重点解析算法的特性与设计要求,并深入讲解时间复杂度分析的核心——大O表示法,通过“只保留最高阶项、忽略常数系数、取最坏情况”三大原则,结合实例剖析O(1)、O(n)等常见时间复杂度,揭示算法效率的本质评估方法。

ACH_YYX的博客 188

数据结构:9.Map和Set

有的讲解会说这里key是标识作用,这种说法其实没有太大意义,就算知道了他是标识value的作用又如何,在实际的使用过程中,我们只会根据具体的效果选择使用的方法等,不会执着于“标识”这种说法。2.由于哈希函数的设计原则太过理论,它仅仅是在认为:这些通过关键码算出来的index不同 的情况下设计的,然而这种理论化的设计原则在遇到冲突时,恰恰就出现了问题,而我们能做的,就是降低冲突率。虽然哈希表的使用过程中存在冲突,但是在实际的使用过程中,哈希表的冲突率是不高的,冲突的个数是可控的。

2602_95646088的博客 201

Vue3 低代码移动表单设计器实战(二):缩放画布下的拖拽系统与树状级联数据结构

本文深入剖析Vue3低代码表单设计器在缩放画布下的拖拽失效问题,揭示SortableJS在CSS Transform下坐标崩溃的数学根源。通过自研独立视觉克隆壳层与逆向几何补偿算法,实现精准拖拽;采用扁平数据存储+运行时树状计算结构,解决级联依赖与深克隆难题,确保逻辑一致性与性能优化,为复杂低代码系统提供可复用的工程范式。

NanChen的博客 343

排序算法深度笔记(上):比较类排序的思想演进与代码实现

与。本文聚焦前者 —— 也就是通过元素间两两比较来确定相对顺序的排序算法,从最朴素的 O (n²) 基础排序,到工业级主流的 O (nlogn) 进阶排序,逐层拆解设计思想、带注释的代码实现与边界细节。当我们理解了比较排序的性能边界,也就自然引出了非比较排序的存在意义。所有代码均遵循统一的实现规范:入口函数前置空数组与单元素边界校验,基于数组原地修改,主函数附带可直接运行的测试用例,与练习代码风格完全对齐。

2401_87069538的博客 611

CF2283F[数据结构]

首先考虑一种暴力解法,当我们建好i之前的图后,当我们添加i的时候,区间[li,ri]中的点都会向i建边,但是这些点中,如果有某两个顶点l,r,满足l<r,那么l就可以通过r间接到达i,因此可以删除l到i的边;初始时我们令所有点放入set中,然后对于每一个i的处理,我们将集合中仍在[l,r]的范围的点弹出,并且将f设置为i,这样我们就得到了所有点的最小跳板;对于每个区间[l,r] 我们要计算这下下标中的f(v)中大于r的数目有多少个;我们令f(v)表示顶点v可到达的最小的顶点;

蒟蒻 138

笔记-论数据结构2

typedef 数据类型 别名return 0;typedef也经常用在结构体上:每次声明结构体变量都要写struct关键字,很麻烦,而且逻辑上也很难受,typedef可以解决这个问题。int x;int y;p.x = 5;p.y = 10;return 0;而利用typedef解决有两种解法:typedef struct 结构体名数据类型 变量名;数据类型 变量名;……}别名;数据类型 变量名;数据类型 变量名;……}别名;实际的运用int x;

fish_zzzz的博客 111

【数据结构-3】算法美学之降复杂度

在while循环的循环体内,首先用临时变量保存最后一个位置的数据,再通过for循环把所有元素往后移动一位,最后把tmp中保存的值放到下标为0的位置上去。方法二的思路是:创建新数组,让原数组中后k个数据移动到新数组中前面的位置,让原数组中前numsSize-k个数据移动到新数组中后面的位置,这。这段代码的思路是:三次逆置,第一次逆置前numsSize-k个数据,第二次逆置后k个数据,最后整体逆置。这篇博文分享一道解法不一的算法题,求解过程的目的在于降低算法的时间复杂度,题源力扣。,属于空间换时间的操作。

weixin_44218929的博客 85

【数据结构-2】顺序表的实现

线性表是一种数据结构,它分为逻辑结构和物理结构,在逻辑结构上线性表是呈线性的,数据是是连续存储的;在物理结构(物理空间)上,线性表不一定是连续存储的。线性表的实现,主要分为数组和链式结构。顺序表是线性表的一种实现方式,顺序表在逻辑结构和物理结构上都是连续的。顺序表的底层实现是数组。

weixin_44218929的博客 208
上一篇: 代码随想录 Day 14 | 【第六章 二叉树】 226.翻转二叉树、101. 对称二叉树、104.二叉树的最大深度、111.二叉树的最小深度
下一篇: 代码随想录 Day 16 | 【第六章 二叉树】找树左下角的值、路径总和、从中序与后序遍历序列构造二叉树
Accept17
博客等级 码龄4年 479粉丝 43原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值