【寸铁的刷题笔记】树、dfs、bfs、回溯、递归(一)

【寸铁的刷题笔记】树、dfs、bfs、回溯、递归(一)

大家好 我是寸铁👊
总结了一篇刷题关于树、dfs、bfs、回溯、递归的文章✨
喜欢的小伙伴可以点点关注 💝


105. 从前序与中序遍历序列构造二叉树

模拟分析图

在这里插入图片描述

代码实现

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public TreeNode buildTree(int[] preorder, int[] inorder) {return buildTree1(preorder , 0 , preorder.length , inorder , 0 , inorder.length);}public TreeNode buildTree1(int []preorder , int preLeft, int preRight , int []inorder , int inLeft , int inRight){//递归终止条件//中序数组中右边界-左边界 < 1//返回nullif(inRight - inLeft < 1){return null;}//只有一个节点//则创建该值的节点返回出去即可if(inRight - inLeft == 1){return  new TreeNode(inorder[inLeft]);}//前序遍历中的第一个值为根节点的值int Val = preorder[preLeft];//记录根节点的下标索引int rootIdx = 0;//在中序数组中查找到第一个值所在的下标//用于根据该下标进行数组的切割TreeNode root = new TreeNode(Val);for(int i = inLeft; i < inRight; i++){if(inorder[i] == Val){rootIdx = i;break;}}//递归根节点的左子树和右子树//注意: 编写递归时要统一规范//由于上面写的是i < inRight//这里需要不断查找每个切分的数组的根节点进行切割。//区间是左闭右开的 要统一规范去写//清楚是左闭右开后 编写逻辑如下:root.left = buildTree1(preorder , preLeft + 1 , preLeft + 1 + (rootIdx - inLeft) , inorder , inLeft , rootIdx);root.right = buildTree1(preorder , preLeft+1+(rootIdx - inLeft) , preRight , inorder , rootIdx + 1 , inRight);//返回最后的根节点//每次递归时,向上返回该节点,接住该节点的是左孩子或者右孩子return root;}
}

106. 从中序与后序遍历序列构造二叉树

模拟分析图

在这里插入图片描述

代码实现

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public TreeNode buildTree(int[] inorder, int[] postorder) {//注:传入的是中序和后序数组的长度//区间是左闭右开return buildTree1(inorder , 0 , inorder.length , postorder , 0 , postorder.length);}public TreeNode buildTree1(int []inorder , int inleft, int inRight , int[]postorder , int postLeft,int postRight){//对中序数组进行判断//如果说中序数组的长度 - 起点下标 < 1 //则说明没有元素 返回空// 0 - 0 = 0 < 1if(inRight - inleft < 1){return null;}//只有一个元素//则创建一个该元素的节点返回即可if(inRight - inleft == 1){return new TreeNode(inorder[inleft]);}//后序数组中的最后一个元素即为根起点int rootVal = postorder[postRight - 1];TreeNode root = new TreeNode(rootVal);int rootIndex = 0;//根据拿到的根节点root在中序数组中找到切割点for(int i = inleft; i < inRight; i++){if(inorder[i] == rootVal){rootIndex = i;}}//根据rootIndex在中、后序数组中划分左右子树//在中序中划分root.left = buildTree1(inorder , inleft , rootIndex, postorder , postLeft , postLeft + (rootIndex - inleft));//在后序中划分        root.right = buildTree1(inorder, rootIndex + 1, inRight , postorder , postLeft + (rootIndex - inleft) , postRight - 1);        return root;}
}

112. 路径总和

代码实现

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {public boolean hasPathSum(TreeNode root, int targetSum) {//如果说根节点为空 则无法得到目标和 直接返回falseif(root == null) return false;//采用的是减法 看最后targetSum 减少到最后是否为0//递归调用 传入根节点 此时count和为targetSum - 当前根节点的值return traversal(root , targetSum - root.val);}public boolean traversal(TreeNode cur , int count){//如果说左子树和右子树都为空(此为叶子节点) 并且count等于0//则说明存在路径使得节点之和为targetSum//返回trueif(cur.left == null && cur.right == null && count == 0)return true;//否则返回falseif(cur.left == null && cur.right == null && count == 0)return false;//递归逻辑//递归左子树if(cur.left != null){//减去当前遍历到的节点值count -= cur.left.val;//注意:这里需要向上返回布尔值//如果往左子树遍历的结果为true//则向上返回trueif(traversal(cur.left , count)){return true;}//回溯 把之前减去的节点值加上//再从另一个分支去寻找是否存在路径count += cur.left.val;}//同理,递归右子树if(cur.right != null){count -= cur.right.val;if(traversal(cur.right , count)){return true;}count += cur.right.val;}return false;}
}

113. 路径总和 II

相比较 112. 路径总和
113. 路径总和 II || 与下面的 129. 求根节点到叶节点数字之和
共同的逻辑都是需要遍历一棵树从根节点到所有叶子节点
这意味着需要一个数据结构(list)去存储所有经过的路径上的节点
也就意味着不需要返回值,但是由于需要遍历所有的叶子节点
这里需要进行向上回溯,也就是怎么来的就怎么去(恢复现场)

代码实现

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {//result队列用于接收满足条件的pathList<List<Integer>> result;//path用于接收每次搜索的结果//这里不用开启全局变量//原因:path会遍历到叶子节点会向上回溯 LinkedList<Integer> path;public List<List<Integer>> pathSum(TreeNode root, int targetSum) {result = new LinkedList<>();path = new LinkedList<>();travesal(root , targetSum);return result;}//这里由于有path接收搜索的结点//所以,这里不需要去返回值public void travesal(TreeNode root , int count){//如果说根节点为空 则直接结束if(root == null) return;//先把当前的节点值加入到path队列中path.offer(root.val);//然后,更新当前的count 把当前添加入队列的节点值减去count -= root.val;//接着,处理临界条件,也就是遍历到叶子节点对答案的判断if(root.left == null && root.right == null && count == 0){//满足条件则把当前遍历的节点添加到path队列中result.add(new LinkedList<>(path));}//向下递归,遍历左子树和右子树//这里是直接往左子树或者右子树的某个方向能走的路走到底//无论是往右还是左走 走到底即可//走到底无路可走后再向上回溯 依次移除最后一个元素 再去搜索其他分支travesal(root.left , count);travesal(root.right , count);path.removeLast();}
}

debug

class Solution {List<List<Integer>> result;LinkedList <Integer> path;public List<List<Integer>> pathSum(TreeNode root, int targetSum) {result = new LinkedList<>();path = new LinkedList<>();travesal(root , targetSum);return result;}public void travesal(TreeNode root , int count){if(root == null)return;path.offer(root.val);count -= root.val;System.out.println("111111111");System.out.println(path);if(root.left == null && root.right == null && count == 0){//打印出来去看path的变化过程System.out.println("22222222");System.out.println(path);result.add(new LinkedList<>(path));}travesal(root.left , count);System.out.println("leftleftleftleftleftleft");System.out.println(path);travesal(root.right , count);System.out.println("333333333333");System.out.println(path);//依次移除掉最后一个节点,向上回溯//直至移除到最后一个根节点path.removeLast();}
}

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

代码实现

/*** Definition for a binary tree node.* public class TreeNode {*     int val;*     TreeNode left;*     TreeNode right;*     TreeNode() {}*     TreeNode(int val) { this.val = val; }*     TreeNode(int val, TreeNode left, TreeNode right) {*         this.val = val;*         this.left = left;*         this.right = right;*     }* }*/
class Solution {//path存储dfs到的节点List<Integer>path = new LinkedList<>();//记录最终求和的结果int res = 0;public int sumNumbers(TreeNode root) {//如果root为null 则返回0if(root == null)return 0;//如果root不为null 则把根节点添加到path中path.add(root.val);travesal(root);return res;}public void travesal(TreeNode root){//遍历到叶子节点则对当前的path的值求和if(root.left == null && root.right == null){res += listToInt(path);}//遍历左子树if(root.left != null){//先添加左子树节点的值path.add(root.left.val);//再继续递归到下一层travesal(root.left);//移除掉当前队列中的最后一个元素 向上回溯path.remove(path.size() - 1);}//遍历右子树if(root.right != null){path.add(root.right.val);travesal(root.right);path.remove(path.size() - 1);}}//对path中存储的节点值进行求和public int listToInt(List<Integer> path){int sum = 0;//这里由于list是队列 先进先出//在原来的sum基础上乘10 再加上最后一个元素即可for(Integer s : path){sum = sum * 10 + s;}return sum;}}

总结

大逻辑其实还是最核心的三个点,一个是根节点,一个是左孩子 ,一个是右孩子
可以把递归函数看成是一个整体部分,整体的去对左子树进行处理,整体
的去对右子树进行处理,然后返回结果或者说记录结果,不必去深究递归里面的细节,会让整个的解题思路变得十分复制混乱,就是理解为递归函数去帮助你进行处理,最后返回一个结果或者将结果存起来就好了!


看到这里的小伙伴,恭喜你又掌握了一个技能👊
希望大家能取得胜利,坚持就是胜利💪
我是寸铁!我们下期再见💕


往期好文💕

保姆级教程

【保姆级教程】Windows11下go-zero的etcd安装与初步使用

【保姆级教程】Windows11安装go-zero代码生成工具goctl、protoc、go-zero

【Go-Zero】手把手带你在goland中创建api文件并设置高亮


报错解决

【Go-Zero】Error: user.api 27:9 syntax error: expected ‘:‘ | ‘IDENT‘ | ‘INT‘, got ‘(‘ 报错解决方案及api路由注意事项

【Go-Zero】Error: only one service expected goctl一键转换生成rpc服务错误解决方案

【Go-Zero】【error】 failed to initialize database, got error Error 1045 (28000):报错解决方案

【Go-Zero】Error 1045 (28000): Access denied for user ‘root‘@‘localhost‘ (using password: YES)报错解决方案

【Go-Zero】type mismatch for field “Auth.AccessSecret“, expect “string“, actual “number“报错解决方案

【Go-Zero】Error: user.api 30:2 syntax error: expected ‘)‘ | ‘KEY‘, got ‘IDENT‘报错解决方案

【Go-Zero】Windows启动rpc服务报错panic:context deadline exceeded解决方案


Go面试向

【Go面试向】defer与time.sleep初探

【Go面试向】defer与return的执行顺序初探

【Go面试向】Go程序的执行顺序

【Go面试向】rune和byte类型的认识与使用

【Go面试向】实现map稳定的有序遍历的方式

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

说一下 JVM 运行时数据区 ?

目录 一、程序计数器&#xff08;Program Counter Register&#xff09; 二、Java 虚拟机栈&#xff08;Java Virtual Machine Stacks&#xff09; 三、本地方法栈&#xff08;Native Method Stack&#xff09; 四、Java 堆&#xff08;Java Heap&#xff09; 五、方法区&…

Imagewheel私人图床搭建结合内网穿透实现无公网IP远程访问教程

文章目录 1.前言2. Imagewheel网站搭建2.1. Imagewheel下载和安装2.2. Imagewheel网页测试2.3.cpolar的安装和注册 3.本地网页发布3.1.Cpolar临时数据隧道3.2.Cpolar稳定隧道&#xff08;云端设置&#xff09;3.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 4.公网访问测…

图——最小生成树实现(Kruskal算法,prime算法)

目录 预备知识&#xff1a; 最小生成树概念&#xff1a; Kruskal算法&#xff1a; 代码实现如下&#xff1a; 测试&#xff1a; Prime算法 &#xff1a; 代码实现如下&#xff1a; 测试&#xff1a; 结语&#xff1a; 预备知识&#xff1a; 连通图&#xff1a;在无向图…

代码随想录第二十三天 回溯算法 77.组合 216.组合总和 17.电话号码的字母组合

回溯算法 LeetCode 77 组合 题目描述 思路 递归函数的返回值以及参数 在这里要定义两个全局变量&#xff0c;一个用来存放符合条件单一结果&#xff0c;一个用来存放符合条件结果的集合。 代码如下&#xff1a; vector<vector<int>> result; // 存放符合条件…

【Java EE初阶十六】网络原理(一)

在网络原理中主要学习TCP/IP四层模型中的重点网络协议 1. 应用层 1.1 应用程序与协议 应用层是和程序员接触最密切的&#xff1b; 应用程序&#xff1a;在应用层这里&#xff0c;很多时候都是程序员自定义应用层协议&#xff08;步骤&#xff1a;1、根据需求&#xff0c;明确…

程序员必备技能----删库跑路大总结

删库跑路大总结&#xff0c;各个都是大杀器&#xff0c;破坏性太大&#xff0c;轻易不要尝试。 删除linux根目录&#xff0c;用户目录&#xff0c;其实还可以增加一个删除/etc。删除&#xff08;清除&#xff09;数据库。删除redis缓存和持久化文件。删除mongodb库。git push …

MCAL知识点(二十七):TC275如何通过GPT12实现ABZ解码

目录 1、概述 2、代码实现 1、概述 GPT12 - General Purpose Timer Unit (GPT12):通用定时器单元,具备较为灵活的定时器结构,可以用来做定时器、事件计数、脉冲宽度测量、产生PWM、频率调制、ABZ编码器增量测量。文章记录一下如何通过GPT12实现编码器ABZ信号的测量。 注意…

c#创建安装windows服务

背景:最近在做设备数据对接采集时,遇到一些设备不是标准的Service-Client接口,导致采集的数据不够准确;比如设备如果中途开关机后,加工的数量就会从0开始重新计数,因此需要实时监控设备的数据,进行叠加处理;考略到工厂设备比较多,实时监听接口的数据为每秒3次,因此将…

week04day01(爬虫)

一. 爬虫 只爬取公开的信息&#xff0c;不能爬取未公开的后台数据 1.爬虫的合法性 法无禁止皆可为 -- 属于法律的灰色地带https://www.tencent.com/robots.txt -- 网站/robots.txt 可以查看禁止爬取的内容 2. URL Uniform Resource Locator 统一资源定位符https://www.…

【国产MCU】-CH32V307-通用定时器(GPTM)-单脉冲模式

通用定时器(GPTM)-单脉冲模式 文章目录 通用定时器(GPTM)-单脉冲模式1、单脉冲模式介绍2、驱动API介绍3、单脉冲使用实例本文将详细介绍如何使用CH32V307通用定时器的单脉冲模式。 1、单脉冲模式介绍 单脉冲模式可以响应一个特定的事件,在一个延迟之后产生一个脉冲,延迟…

Sora--首个大型视频生成模型

Sora--首个大型视频生成模型 胡锡进于2024年2月20日认为&#xff1a;台当局怂了 新的改变世界模拟器视觉数据转换视频压缩时空补丁&#xff08;Spacetime Laten Patches&#xff09;视频生成扩展变压器算法和模型架构结语 胡锡进于2024年2月20日认为&#xff1a;台当局怂了 **T…

AI Agent规划能力全面拆解

“规划今天和每天的工作&#xff0c;然后执行规划” -- 撒切尔夫人 规划&#xff0c;无论对于人类还是智能体而言&#xff0c;本质上是一种预先设定行动的过程&#xff0c;以期望通过这些行动达到特定的目标或解决特定的问题。制定一个好的规划涉及对未来情景的预测、资源的…

机器学习面试:逻辑回归与朴素贝叶斯区别

逻辑回归与朴素贝叶斯区别有以下几个方面: (1)逻辑回归是判别模型&#xff0c;朴素贝叶斯是生成模型&#xff0c;所以生成和判别的所有区别它们都有。 (2)朴素贝叶斯属于贝叶斯&#xff0c;逻辑回归是最大似然&#xff0c;两种概率哲学间的区别。 (3)朴素贝叶斯需要条件独立假设…

ClickHouse--12-可视化工具操作

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 可视化工具操作1 tabixhttp://ui.tabix.io/ 2 DBeaverhttps://dbeaver.io/download/ 可视化工具操作 1 tabix tabix 支持通过浏览器直接连接 ClickHouse&#xff…

【Django】Django自定义后台表单——对一个关联外键对象同时添加多个内容

以官方文档为例&#xff1a; 一个投票问题包含多个选项&#xff0c;基本的表单设计只能一个选项一个选项添加&#xff0c;效率较低&#xff0c;如何在表单设计中一次性添加多个关联选项&#xff1f; 示例代码&#xff1a; from django.contrib import adminfrom .models impo…

springboot207基于springboot的实习管理系统

实习管理系统的设计与实现 摘要 近年来&#xff0c;信息化管理行业的不断兴起&#xff0c;使得人们的日常生活越来越离不开计算机和互联网技术。首先&#xff0c;根据收集到的用户需求分析&#xff0c;对设计系统有一个初步的认识与了解&#xff0c;确定实习管理系统的总体功…

消息队列MQ 保证消息不丢失(消息可靠性)

文章目录 概述RabbitMQ 怎么避免消息丢失&#xff08;可靠传输&#xff09;RocketMQ 怎么确保消息不丢失Kafka 怎么保证消息不丢失activeMQ 怎么避免消息丢失MQ 宕机了消息是否会丢失线上服务宕机时&#xff0c;如何保证数据100%不丢失吗&#xff1f;消息队列消息持久化 概述 …

一周学会Django5 Python Web开发-Django5路由重定向

锋哥原创的Python Web开发 Django5视频教程&#xff1a; 2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili2024版 Django5 Python web开发 视频教程(无废话版) 玩命更新中~共计25条视频&#xff0c;包括&#xff1a;2024版 Django5 Python we…

JDK8 升级至JDK19

优质博文IT-BLOG-CN 目前部分项目使用JDK8&#xff0c;部分项目使用JDK19因此&#xff0c;环境变量中还是保持JDK8&#xff0c;只需要下载JDK19免安装版本&#xff0c;通过配置IDEA就可以完成本地开发。 一、IDEA 环境设置 【1】通过快捷键CTRL SHIFT ALT S或者File->P…

【SpringBoot3】Spring Security 常用注解

注&#xff1a;本文基于Spring Boot 3.2.1 以及 Spring Security 6.2.1 Spring Security 6 的常用注解包括以下几种&#xff0c;通过这些注解可以更加方便的控制资源权限。 Secured &#xff1a;方法执行前检查&#xff0c;直接判断有没有对应的角色PreAuthorize&#xff1a;方…