二叉树 递归

news2025/4/5 10:29:07

本篇基于b站灵茶山艾府的课上例题与课后作业。

104. 二叉树的最大深度

给定一个二叉树 root ,返回其最大深度。

二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。

示例 1:

img

输入:root = [3,9,20,null,null,15,7]
输出:3

示例 2:

输入:root = [1,null,2]
输出: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 maxDepth(self, root: Optional[TreeNode]) -> int:
        # 方法1:自底向上(归)
        # def dfs(node):
        #     if node == None:
        #         return 0
        #     return max(dfs(node.left), dfs(node.right)) + 1

        # return dfs(root)

        # 方法2:自顶向下(递)
        ans = 0     

        def dfs(node, cnt):
            if node == None:
                return
            nonlocal ans
            ans = max(ans, cnt)
            dfs(node.left, cnt + 1)
            dfs(node.right, cnt + 1)

        dfs(root, 1)
        return ans


111. 二叉树的最小深度

给定一个二叉树,找出其最小深度。

最小深度是从根节点到最近叶子节点的最短路径上的节点数量。

**说明:**叶子节点是指没有子节点的节点。

示例 1:

img

输入:root = [3,9,20,null,null,15,7]
输出:2

示例 2:

输入:root = [2,null,3,null,4,null,5,null,6]
输出:5

# 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 minDepth(self, root: Optional[TreeNode]) -> int:
        # 方法1:自底向上(归)
        # def dfs(root):
        #     # 由于是找从根节点到最近 叶子 节点的深度,所以我们的边界条件是判断叶子节点,而不是单单空节点
        #     if root.left == None and root.right == None:
        #         return 1
        #     if root.left == None and root.right != None:
        #         return dfs(root.right) + 1
        #     if root.right == None and root.left != None:
        #         return dfs(root.left) + 1

        #     return min(dfs(root.left), dfs(root.right)) + 1

        # if root == None:
        #     return 0
        # return dfs(root)

        # 方法2:自顶向下(归)
        ans = float("inf")

        def dfs(root, cnt):
            nonlocal ans
            if cnt >= ans:  # 剪枝,继续往下递也不会让cnt变小
                return
            if root.left == None and root.right == None:
                ans = min(cnt, ans)
                return
            elif root.left == None and root.right != None:
                dfs(root.right, cnt + 1)
            elif root.right == None and root.left != None:
                dfs(root.left, cnt + 1)
            else:
                dfs(root.left, cnt + 1)
                dfs(root.right, cnt + 1)

        if root == None:
            return 0
        dfs(root, 1)
        return ans


112. 路径总和

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false

叶子节点 是指没有子节点的节点。

示例 1:

img

输入:root = [5,4,8,11,null,13,4,7,2,null,null,null,1], targetSum = 22
输出:true
解释:等于目标和的根节点到叶节点路径如上图所示。

示例 2:

img

输入:root = [1,2,3], targetSum = 5
输出:false
解释:树中存在两条根节点到叶子节点的路径:
(1 --> 2): 和为 3
(1 --> 3): 和为 4
不存在 sum = 5 的根节点到叶子节点的路径。

示例 3:

输入:root = [], targetSum = 0
输出: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 hasPathSum(self, root: Optional[TreeNode], targetSum: int) -> bool:
        # 若根节点有左孩子,那么可以将问题分解为从左孩子到它的叶子节点的路径总和是否等于target-root.val
        # 若有右孩子也是同理,从而将此问题分解为一个个子问题

        def dfs(root, target):
            # 这道题边界条件还是题目所说的叶子节点
            if root.left == None and root.right == None:
                if target == root.val:
                    return True
                else:
                    return False

            # 加这两个判断是为了下面的return,避免dfs里面传入了空节点报错
            if root.left == None and root.right != None:
                return dfs(root.right, target - root.val)
            if root.right == None and root.left != None:
                return dfs(root.left, target - root.val)

            return dfs(root.left, target - root.val) or dfs(root.right, target - root.val)

        if root == None:
            return False
        return dfs(root, targetSum)


129. 求根节点到叶节点数字之和

给你一个二叉树的根节点 root ,树中每个节点都存放有一个 09 之间的数字。

每条从根节点到叶节点的路径都代表一个数字:

  • 例如,从根节点到叶节点的路径 1 -> 2 -> 3 表示数字 123

计算从根节点到叶节点生成的 所有数字之和

叶节点 是指没有子节点的节点。

示例 1:

img

输入:root = [1,2,3]
输出:25
解释:
从根到叶子节点路径 1->2 代表数字 12
从根到叶子节点路径 1->3 代表数字 13
因此,数字总和 = 12 + 13 = 25

示例 2:

img

输入:root = [4,9,0,5,1]
输出:1026
解释:
从根到叶子节点路径 4->9->5 代表数字 495
从根到叶子节点路径 4->9->1 代表数字 491
从根到叶子节点路径 4->0 代表数字 40
因此,数字总和 = 495 + 491 + 40 = 1026

# 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 sumNumbers(self, root: Optional[TreeNode]) -> int:
        ans = 0

        # val存储路径上的数字,用字符串拼接
        def dfs(root, val):
            nonlocal ans
            if root.left == None and root.right == None:
                # 当遇到叶子节点,拼接后记录结果
                ans += int(val + str(root.val))
            elif root.left == None and root.right != None:
                return dfs(root.right, val + str(root.val))
            elif root.right == None and root.left != None:
                return dfs(root.left, val + str(root.val))
            else:
                dfs(root.left, val + str(root.val))
                dfs(root.right, val + str(root.val))

        dfs(root, "")
        return ans


1448. 统计二叉树中好节点的数目

给你一棵根为 root 的二叉树,请你返回二叉树中好节点的数目。

「好节点」X 定义为:从根到该节点 X 所经过的节点中,没有任何节点的值大于 X 的值。

示例 1:

img

输入:root = [3,1,4,3,null,1,5]
输出:4
解释:图中蓝色节点为好节点。
根节点 (3) 永远是个好节点。
节点 4 -> (3,4) 是路径中的最大值。
节点 5 -> (3,4,5) 是路径中的最大值。
节点 3 -> (3,1,3) 是路径中的最大值。

示例 2:

img

输入:root = [3,3,null,4,2]
输出:3
解释:节点 2 -> (3, 3, 2) 不是好节点,因为 "3" 比它大。

示例 3:

输入:root = [1]
输出: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 goodNodes(self, root: Optional[TreeNode]) -> int:
        ans = 0
        # 传入参数的val表示当前节点之前所有可能的路径中节点的最大值
        def dfs(root, val):
            nonlocal ans
            if root == None:
                return
            # 如果遇到的节点比最大值大,说明前面的节点一定比当前节点小,则记录结果,同时更新最大值
            if root.val >= val:
                val = root.val
                ans += 1
            dfs(root.right, val)
            dfs(root.left, val)

        dfs(root, -10001)
        return ans


987. 二叉树的垂序遍历

给你二叉树的根结点 root ,请你设计算法计算二叉树的 垂序遍历 序列。

对位于 (row, col) 的每个结点而言,其左右子结点分别位于 (row + 1, col - 1)(row + 1, col + 1) 。树的根结点位于 (0, 0)

二叉树的 垂序遍历 从最左边的列开始直到最右边的列结束,按列索引每一列上的所有结点,形成一个按出现位置从上到下排序的有序列表。如果同行同列上有多个结点,则按结点的值从小到大进行排序。

返回二叉树的 垂序遍历 序列。

示例 1:

img

输入:root = [3,9,20,null,null,15,7]
输出:[[9],[3,15],[20],[7]]
解释:
列 -1 :只有结点 9 在此列中。
列  0 :只有结点 3 和 15 在此列中,按从上到下顺序。
列  1 :只有结点 20 在此列中。
列  2 :只有结点 7 在此列中。

示例 2:

img

输入:root = [1,2,3,4,5,6,7]
输出:[[4],[2],[1,5,6],[3],[7]]
解释:
列 -2 :只有结点 4 在此列中。
列 -1 :只有结点 2 在此列中。
列  0 :结点 1 、5 和 6 都在此列中。
          1 在上面,所以它出现在前面。
          5 和 6 位置都是 (2, 0) ,所以按值从小到大排序,5 在 6 的前面。
列  1 :只有结点 3 在此列中。
列  2 :只有结点 7 在此列中。

示例 3:

img

输入:root = [1,2,3,4,6,5,7]
输出:[[4],[2],[1,5,6],[3],[7]]
解释:
这个示例实际上与示例 2 完全相同,只是结点 5 和 6 在树中的位置发生了交换。
因为 5 和 6 的位置仍然相同,所以答案保持不变,仍然按值从小到大排序。

# 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 verticalTraversal(self, root: Optional[TreeNode]) -> List[List[int]]:
        from collections import defaultdict
        #哈希表,键为节点所在的列,值为(行,值)
        li = defaultdict(list)

        def dfs(root, i, j):
            if root == None:
                return
            li[j].append((i, root.val))
            dfs(root.left, i + 1, j - 1)
            dfs(root.right, i + 1, j + 1)

        dfs(root, 0, 0)
        res = []
        # sorted*(li.items()):给哈希表中按键排序
        for key, values in sorted(li.items()):
            # 给值里面的列表排序,列表里面为元组,排序依据为元组的第一个值,再第二个值
            values.sort()
            res.append([i[1] for i in values])
        return res

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

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

相关文章

反常积分和定积分的应用 2

世界尚有同类 前言伽马函数的推论关于数学的思考平面图形的面积笛卡尔心形线伯努利双纽线回顾参数方程求面积星型线摆线 旋转体体积一般轴线旋转被积函数有负数部分曲线的弧长最后一个部分内容-旋转曲面侧表面积直角坐标系极坐标系参数方程 总结 前言 力大出奇迹。好好加油。 …

Element-plus弹出框popover,使用自定义的图标选择组件

自定义的图标选择组件是若依的项目的 1. 若依的图标选择组件 js文件,引入所有的svg图片 let icons [] // 注意这里的路径,一定要是自己svg图片的路径 const modules import.meta.glob(./../../assets/icons/svg/*.svg); for (const path in modules)…

思维链 Chain-of-Thought(COT)

思维链 Chain-of-Thought(COT):思维链的启蒙 3. 思维链 Chain-of-Thought(COT)存在问题?2. 思维链 Chain-of-Thought(COT)是思路是什么?1. 什么是 思维链 Chain-of-Thoug…

硬件电路(23)-输入隔离高低电平有效切换电路

一、概述 项目中为了防止信号干扰需要加一些隔离电路,而且有时传感器的信号是高有效有时是低有效,所以基于此背景,设计了一款方便实现高低电平有效检测切换电路。 二、应用电路

大模型学习二:DeepSeek R1+蒸馏模型组本地部署与调用

一、说明 DeepSeek R1蒸馏模型组是基于DeepSeek-R1模型体系,通过知识蒸馏技术优化形成的系列模型,旨在平衡性能与效率。 1、技术路径与核心能力 基础架构与训练方法‌ ‌DeepSeek-R1-Zero‌:通过强化学习(RL)训练&…

相机的曝光和增益

文章目录 曝光增益增益原理主要作用增益带来的影响增益设置与应用 曝光 参考:B站优致谱视觉 增益 相机增益是指相机在拍摄过程中对图像信号进行放大的一种操作,它在提高图像亮度和增强图像细节方面起着重要作用,以下从原理、作用、影响以…

Linux内核物理内存组织结构

一、系统调用sys_mmap 系统调用mmap用来创建内存映射,把创建内存映射主要的工作委托给do_mmap函数,内核源码文件处理:mm/mmap.c 二、系统调用sys_munmap 1、vma find_vma (mm, start); // 根据起始地址找到要删除的第一个虚拟内存区域 vma 2…

(多看) CExercise_05_1函数_1.2计算base的exponent次幂

题目: 键盘录入两个整数:底(base)和幂指数(exponent),计算base的exponent次幂,并打印输出对应的结果。(注意底和幂指数都可能是负数) 提示:求幂运算时,基础的思路就是先无脑把指数转…

Vuue2 element-admin管理后台,Crud.js封装表格参数修改

需求 表格数据调用列表接口,需要多传一个 Type字段,而Type字段的值 需要从跳转页面Url上面获取到,并赋值给Type,再传入列表接口中,最后拿到表格数据并展示 遇到的问题 需求很简单,但是因为表格使用的是统…

Tiktok矩阵运营中使用云手机的好处

Tiktok矩阵运营中使用云手机的好处 云手机在TikTok矩阵运营中能够大幅提高管理效率、降低封号风险,并节省成本,是非常实用的运营工具。TikTok矩阵运营使用云手机有很多优势,特别是对于需要批量管理账号、提高运营效率的团队来说。以下是几个…

Linux下调试器gdb_cgdb使用

文章目录 一、样例代码二、使用watchset var确定问题原因条件断点 一、样例代码 #include <stdio.h>int Sum(int s, int e) {int result 0;int i;for(i s; i < e; i){result i;}return result; }int main() {int start 1;int end 100;printf("I will begin…

Vite环境下解决跨域问题

在 Vite 开发环境中&#xff0c;可以通过配置代理来解决跨域问题。以下是具体步骤&#xff1a; 在项目根目录下找到 vite.config.js 文件&#xff1a;如果没有&#xff0c;则需要创建一个。配置代理&#xff1a;在 vite.config.js 文件中&#xff0c;使用 server.proxy 选项来…

超简单:Linux下opencv-gpu配置

1.下载opencv和opencv_contrib安装包 1&#xff09;使用命令下 git clone https://github.com/opencv/opencv.git -b 4.9.0 git clone https://github.com/opencv/opencv_contrib.git -b 4.9.02&#xff09;复制链接去GitHub下载然后上传到服务器 注意&#xff1a;看好版本&a…

泰博云平台solr接口存在SSRF漏洞

免责声明&#xff1a;本号提供的网络安全信息仅供参考&#xff0c;不构成专业建议。作者不对任何由于使用本文信息而导致的直接或间接损害承担责任。如涉及侵权&#xff0c;请及时与我联系&#xff0c;我将尽快处理并删除相关内容。 漏洞描述 SSRF漏洞是一种在未能获取服务器…

31天Python入门——第20天:魔法方法详解

你好&#xff0c;我是安然无虞。 文章目录 魔法方法1. __new__和__del__2. __repr__和__len__3. __enter__和__exit__4. 可迭代对象和迭代器5. 中括号[]数据操作6. __getattr__、__setattr__ 和 __delattr__7. 可调用的8. 运算符 魔法方法 魔法方法: Python中的魔法方法是一类…

ubantu22.04中搭建地图开发环境(qt5.15.2 + osg3.7.0 + osgearth3.7.1 + osgqt)

一、下载安装qt5.15.2 二、下载编译安装osg3.7.0 三、下载编译安装osgearth3.7.1 四、下载编译安装osgqt 五、二三维地图显示demo开发 六、成果展示&#xff1a; 已有功能&#xff1a;加载了dom影像、可以进行二三维地图切换显示、二维地图支持缩放和平移、三维地图支持旋转…

Bethune X 6发布:为小规模数据库环境打造轻量化智能监控巡检利器

3月31日&#xff0c;“奇点时刻・数智跃迁 -- 云和恩墨2025春季产品发布会”通过视频号直播的方式在线上举办。发布会上&#xff0c;云和恩墨副总经理熊军正式发布 zCloud 6.7和zData X 3.3两款产品新版本&#xff0c;同时也带来了 Bethune X 6——这款面向小规模数据库环境的智…

一文理解什么是中值模糊

目录 中值模糊的概念 中值模糊&#xff08;Median Blur&#xff09; 中值模糊的原理 示例&#xff1a;33 中值模糊 什么是椒盐噪声 椒盐噪声&#xff08;Salt-and-Pepper Noise&#xff09; 椒盐噪声的特点 OpenCV 中的 cv2.medianBlur() 函数格式 示例代码 中值模糊…

游戏引擎学习第192天

仓库:https://gitee.com/mrxiao_com/2d_game_4 回顾 我们现在正在编写一些界面代码&#xff0c;主要是用户界面&#xff08;UI&#xff09;&#xff0c;不过这里的UI并不是游戏内的用户界面&#xff0c;而是为开发者设计的用户界面。我们正在尝试做一些小的UI元素&#xff0c…

通信数据记录仪-产品概念ID

总结: 1、支持高速CAN、支持容错CAN、支持单线CAN(理解是支持不同的协议,CANFD、CAN2.0和LIN?) 2、 通过上位机设计时间