当前位置: 首页 > news >正文

算法妙妙屋-------1.递归的深邃回响:二叉树的奇妙剪枝

大佬们好呀,这一次讲解的是二叉树的深度搜索,大佬们请阅

1.前言

⼆叉树中的深搜(介绍)

深度优先遍历(DFS,全称为DepthFirstTraversal),是我们树或者图这样的数据结构中常⽤的⼀种***遍历算法***。这个算法会尽可能深的搜索树或者图的分⽀,直到⼀条路径上的所有节点都被遍历完毕,然后再回溯到上⼀层,继续找⼀条路遍历。
在⼆叉树中,常⻅的深度优先遍历为:前序遍历中序遍历以及后序遍历
因为树的定义本⾝就是递归定义,因此采⽤递归的⽅法去实现树的三种遍历不仅容易理解⽽且代码很简洁。并且前中后序三种遍历的唯⼀区别就是 ***访问根节点的时机不同***,在做题的时候,选择⼀个适当的遍历顺序,对于算法的理解是⾮常有帮助的。

好了,接下来让我们用习题来介绍吧

1.计算布尔⼆叉树的值(medium)

题目链接:计算布尔二叉树的值
题目介绍:

给你⼀棵完整⼆叉树的根,这棵树有以下特征:
叶⼦节点要么值为0要么值为1,其中0表⽰False,1表⽰True。
⾮叶⼦节点要么值为2要么值为3,其中2表⽰逻辑或OR,3表⽰逻辑与AND。
计算⼀个节点的值⽅式如下:
如果节点是个叶⼦节点,那么节点的值为它本⾝,即True或者False。
否则,计算两个孩⼦的节点值,然后将该节点的运算符对两个孩⼦值进⾏运算。
返回根节点root的布尔运算值。
完整⼆叉树是每个节点有0个或者2个孩⼦的⼆叉树。
叶⼦节点是没有孩⼦的节点。

在这里插入图片描述

算法思路:

    1. 对于规模为n的问题,需要求得当前节点值。
    1. 节点值不为0或1时, ***规模为n的问题可以被拆分为规模为n-1的⼦问题***:
  • a:所有⼦节点的值;
  • b:通过⼦节点的值运算出当前节点值。
    1. 当问题的规模变为n=1时,即叶⼦节点的值为0或1,我们可以直接获取当前节点值为0或1。

递归函数流程:

    1. 当前问题规模为n=1时,即叶⼦节点,直接返回当前节点值
    1. 递归求得左右⼦节点的值;
    1. 通过***判断当前节点的逻辑运算符***,计算左右⼦节点值运算得出的结果;

代码如下:

class Solution {
public:bool evaluateTree(TreeNode* root) {if(root->left==nullptr||root->right==nullptr){return root->val;}else{if(root->val==2)return evaluateTree(root->left)||evaluateTree(root->right);elsereturn evaluateTree(root->left)&&evaluateTree(root->right);}}
};

2. 求根节点到叶节点数字之和(medium)

题目链接:求根节点到叶节点数字之和
题目介绍:
给你⼀个⼆叉树的根节点root,树中每个节点都存放有⼀个0到9之间的数字。
每条从根节点到叶节点的路径都代表⼀个数字:
例如,从根节点到叶节点的路径1->2->3表⽰数字123。
计算从根节点到叶节点⽣成的所有数字之和。
叶节点是指没有⼦节点的节点。

在这里插入图片描述
解题思路:

解法(dfs-前序遍历)

前序遍历按照根节点、左⼦树、右⼦树的顺序遍历⼆叉树的所有节点,通常⽤于 ⼦节点的状态依赖于⽗节点状态的题⽬

在前序遍历的过程中,我们可以 往左右⼦树传递信息,并且在回溯时得到左右⼦树的返回值。递归函数可以帮我们完成两件事:

  • 将⽗节点的数字与当前节点的信息整合到⼀起,计算出当前节点的数字,然后传递到下⼀层进⾏递归;
  • 当遇到叶⼦节点的时候,就***不再向下传递信息***,⽽是 ***将整合的结果向上⼀直回溯到根节点***。在递归结束时,根节点需要返回的值也就被更新为了整棵树的数字和。

递归函数流程:

    1. 当遇到空节点的时候,说明这条路从根节点开始没有分⽀,返回0
    1. 结合⽗节点传下的信息以及当前节点的val,计算出当前节点数字sum
    1. 如果当前结点是叶⼦节点,直接返回整合后的结果sum
    1. 如果当前结点不是叶⼦节点,将sum传到左右⼦树中去得到左右⼦树中节点路径的数字和,然后 ***相加后返回结果***。

代码如下:

class Solution {
public:int sumNumbers(TreeNode* root) {return sumNumber(root,0);}int sumNumber(TreeNode* root,int x) {if(root==nullptr)return x;else{x=x*10+root->val;}if(root->left!=nullptr&&root->right!=nullptr)return sumNumber(root->left,x)+sumNumber(root->right,x);else if(root->left!=nullptr)return sumNumber(root->left,x);else if(root->right!=nullptr)return sumNumber(root->right,x);elsereturn x;}
};

3.⼆叉树剪枝(medium)

题⽬链接:二叉树剪枝

题目介绍:

给你⼆叉树的根结点root,此外树的每个结点的值要么是0,要么是1。
返回移除了所有不包含1的⼦树的原⼆叉树。
节点node的⼦树为node本⾝加上所有node的后代。

在这里插入图片描述
解法(dfs-后序遍历):
后序遍历按照左⼦树、右⼦树、根节点的顺序遍历⼆叉树的所有节点,通常⽤于 ⽗节点的状态依赖于⼦节点状态的题⽬

后序遍历的主要流程:

    1. 递归出⼝:当传⼊节点为空时,不做任何处理;
    1. 递归处理***左⼦树***;
    1. 递归处理***右⼦树***;
    1. 处理当前节点:判断该节点是否为叶⼦节点(即左右⼦节点均被删除,前点成为叶⼦节点),并且节点的值为0
      a. 如果是,就删除掉;
      b. 如果不是,就不做任何处理

代码如下:

class Solution {
public:TreeNode* pruneTree(TreeNode* root) {dfs(root);if(root->left==nullptr&&root->right==nullptr&&root->val==0)return nullptr;elsereturn root;}bool dfs(TreeNode* root) {if (root) {if(root->left==nullptr&&root->right==nullptr)return root->val;bool l = dfs(root->left);bool r = dfs(root->right);if (l == false) {root->left = nullptr;}if (r == false) {root->right = nullptr;}if(root->val==0)return l || r;elsereturn 1;}elsereturn false;}
};

4. ⼆叉搜索树中第k⼩的元素(medium)

题目链接:⼆叉搜索树中第k⼩的元素

题目描述:
给定一个二叉搜索树的根节点 root ,和一个整数 k ,请你设计一个算法查找其中第 k 小的元素(从 1 开始计数)。

在这里插入图片描述
解题思路:
(中序遍历+计数器剪枝)
上述解法不仅使⽤⼤量额外空间存储数据,并且会将所有的结点都遍历⼀遍。
但是,我们可以根据中序遍历的过程,只需扫描前k个结点即可。
因此,我们可以创建⼀个全局的计数器***count***,将其初始化为***k***,每遍历⼀个节点就将***count–***。直到某次递归的时候,count的值等于0,说明此时的结点就是我们要找的结果。

代码如下:

class Solution {
public:int kthSmallest(TreeNode* root, int k) {int flag = 0;dfs(root, k, flag);return flag;}void dfs(TreeNode* root, int& k, int& flag) {if (root) {dfs(root->left, k, flag);k--;if (k == 0) {flag = root->val;}dfs(root->right, k, flag);}}
};

好啦,递归问题就讲到这里,下一次讲解的是搜索,回溯和全排列,我们下次再见

相关文章:

算法妙妙屋-------1.递归的深邃回响:二叉树的奇妙剪枝

大佬们好呀,这一次讲解的是二叉树的深度搜索,大佬们请阅 1.前言 ⼆叉树中的深搜(介绍) 深度优先遍历(DFS,全称为DepthFirstTraversal),是我们树或者图这样的数据结构中常⽤的⼀种…...

编写第一个 Appium 测试脚本:从安装到运行!

前言 最近接到一个测试项目,简单描述一下,需求就是:一端发送指令,另一端接受指令并处理指令。大概看了看有上百条指令,点点点岂不是废了,而且后期迭代,每次都需要点点点,想想就头大…...

mysql查表相关练习

作业要求: 单表练习: 1 . 查询出部门编号为 D2019060011 的所有员工 2 . 所有财务总监的姓名、编号和部门编号。 3 . 找出奖金高于工资的员工。 4 . 找出奖金高于工资 40% 的员工。 5 找出部门编号为 D2019090011 中所有财务总监,和…...

airtest+poco多脚本、多设备批处理运行测试用例自动生成测试报告

一:主要内容 框架功能、框架架构及测试报告效果 airtest安装、环境搭建 框架搭建、框架运行说明 框架源码 二:框架功能及测试报告效果 1. 框架功能: 该框架笔者用来作为公司的项目的前端自动化,支持pc和app,本文…...

Prometheus套装部署到K8S+Dashboard部署详解

1、添加helm源并更新 helm repo add prometheus-community https://prometheus-community.github.io/helm-charts helm repo update2、创建namespace kubectl create namespace monitoring 3、安装Prometheus监控套装 helm install prometheus prometheus-community/prome…...

python使用pymysql

为了封装这个数据库操作为一个通用方法,我们可以创建一个函数,该函数接受数据库连接参数(如主机名、用户名、密码、数据库名)、SQL语句以及必要的参数(用于参数化查询)。下面是一个简单的封装示例&#xff…...

Vue3 + TypeScript 组件和文件命名规范及 setup 导入顺序规范

前言 在 Vue3 项目中,合理的文件命名规范和导入顺序不仅有助于提高代码的可读性,还能增强团队协作的效率。特别是在使用 TypeScript 和 Composition API 的项目中,清晰的组件和文件结构尤为重要。本文将详细介绍 Vue3 TypeScript 项目中的组…...

netty之处理连接源码分析

写在前面 在这篇文章看了netty服务是如何启动的,服务启动成功后,也就相当于是迎宾工作都已经准备好了,那么当客人来了怎么招待客人呢?也就是本文要看的处理连接的工作。 1:正文 先启动源码example模块的echoserver&a…...

Dockerfile文件编写

1、打nginx原始包 登录后复制 ROM nginxENV LANG zh_CN.UTF-8 ENV LC_ALL zh_CN.UTF-8 ENV TZ Asia/Singapore# 设置时区,同样保持在一层 RUN ln -sf /usr/share/zoneinfo/${TZ} /etc/localtime && \echo "${TZ}" > /etc/timezoneRUN apt-get …...

Oracle SQL 使用 ROWNUM 分页查询速度太慢的问题及解决方案!

在使用 Oracle 数据库进行数据查询时,分页查询是一种常见的需求。传统上,开发者常常使用 ROWNUM 来实现分页功能。 然而,当数据量较大时,使用 ROWNUM 进行分页查询可能会导致性能问题。本文将深入探讨这一问题的原因,并提供多种解决方案,以提高分页查询的性能。 一、RO…...

Django3 + Vue.js 前后端分离书籍添加项目Web开发实战

文章目录 Django3后端项目创建切换数据库创建Django实战项目App新建Vue.js前端项目 Django3后端项目创建 创建Django项目,采用Pycharm或者命令行创建皆可。此处,以命令行方式作为演示,项目名为django_vue。 django-admin startproject djang…...

楼梯区域分割系统:Web效果惊艳

楼梯区域分割系统源码&数据集分享 [yolov8-seg-FocalModulation&yolov8-seg-GFPN等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI Global Al l…...

Day10加一

给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。 最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。 你可以假设除了整数 0 之外,这个整数不会以零开头。 class Solution {public int[] plusOne(int[] di…...

UTF-8简介

UTF-8 UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,也是一种前缀码。它可以用一至四个字节对Unicode字符集中的所有有效编码点进行编码,属于Unicode标准的一部分,最初由肯汤普逊…...

基于Openwrt系统架构,实现应用与驱动的实例。

一、在openwrt系统架构,编写helloworld的应用程序。 第一步先创建目录,项目代码要放在 openwrt根目下的 package 目录中,这里源码写在了 hellworld 的 src 目录下,因为外层还有需要编写的文件。 mkdir -p ~/openwrt/package/hel…...

SQL进阶技巧:如何利用三次指数平滑模型预测商品零售额?

目录 0 问题背景 1 数据准备 2 问题解决 2.1 模型构建 (1)符号规定 (2)基本假设...

HTB:Cicada[WriteUP]

目录 连接至HTB服务器并启动靶机 使用nmap对靶机进行开放端口扫描 使用nmap对靶机开放端口进行脚本、服务信息扫描 首先尝试空密码连接靶机SMB服务 由于不知道账户名,这里我们使用crackmapexec对smb服务进行用户爆破 通过该账户连接至靶机SMB服务器提取敏感信…...

小张求职记四

学校食堂的装修富丽堂皇,像个金碧辉煌的宫殿,可实际上却充斥着廉价的塑料制品和刺鼻的消毒水味。这金玉其外败絮其中的景象,与食堂承包商的“精明算计”如出一辙。 小张和小丽应约来到了一个档口下,“红烧肉”,之前就是…...

适用于 c++ 的 wxWidgets框架源码编译SDK-windows篇

本文章记录了下载wxWidgets源码在windows 11上使用visual Studio 2022编译的全过程,讲的不详细请给我留言,让我知道错误并改进。 本教程是入门级。有更深入的交流可以留言给我。 如今互联网流行现在大家都忘记了这块桌面的开发,我认为桌面应用还是有用武之地,是WEB无法替代…...

flink 内存配置(二):设置TaskManager内存

TaskManager在Flink中运行用户代码。根据需要配置内存使用,可以极大地减少Flink的资源占用,提高作业的稳定性。 注意下面的讲解适用于TaskManager 1.10之后的版本。与JobManager进程的内存模型相比,TaskManager内存组件具有类似但更复杂的结构…...

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

Mac软件卸载指南,简单易懂!

刚和Adobe分手&#xff0c;它却总在Library里给你写"回忆录"&#xff1f;卸载的Final Cut Pro像电子幽灵般阴魂不散&#xff1f;总是会有残留文件&#xff0c;别慌&#xff01;这份Mac软件卸载指南&#xff0c;将用最硬核的方式教你"数字分手术"&#xff0…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

R语言速释制剂QBD解决方案之三

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

站群服务器的应用场景都有哪些?

站群服务器主要是为了多个网站的托管和管理所设计的&#xff0c;可以通过集中管理和高效资源的分配&#xff0c;来支持多个独立的网站同时运行&#xff0c;让每一个网站都可以分配到独立的IP地址&#xff0c;避免出现IP关联的风险&#xff0c;用户还可以通过控制面板进行管理功…...

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要

根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分&#xff1a; 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...