【寸铁的刷题笔记】树、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.mzph.cn/news/696138.shtml

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

相关文章

HarmonyOS—添加/删除Module

Module是应用/服务的基本功能单元&#xff0c;包含了源代码、资源文件、第三方库及应用/服务配置文件&#xff0c;每一个Module都可以独立进行编译和运行。一个HarmonyOS应用/服务通常会包含一个或多个Module&#xff0c;因此&#xff0c;可以在工程中创建多个Module&#xff0…

如何利用内网穿透工具在企业微信开发者中心实现本地接口服务回调

文章目录 1. Windows安装Cpolar2. 创建Cpolar域名3. 创建企业微信应用4. 定义回调本地接口5. 回调和可信域名接口校验6. 设置固定Cpolar域名7. 使用固定域名校验 企业微信开发者在应用的开发测试阶段&#xff0c;应用服务通常是部署在开发环境&#xff0c;在有数据回调的开发场…

前端知识复习

1.symbol类型 Symbol 是 ECMAScript 6 中引入的一种新的基本数据类型&#xff0c;它表示独一无二的值。Symbol 值是通过 Symbol() 函数创建的。 Symbol 值具有以下特点&#xff1a; 独一无二性&#xff08;唯一性&#xff09;&#xff1a;每个通过 Symbol() 函数创建的 Symb…

十三:集合

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 01、Java 集合框架概述1.1、集合框架与数组的对比及概述1.2、集合框架涉及到的API 02、Collection接口方法2.1、Collection接口中的常用方法12.2、Collection接口中…

在idea中配置Tomcat

1.在idea中点击右上角 2.点击Edit Configurations,点击加号 3.向下拉找到Tomcat Server下的Local,点一下 点击Configure 找到tomcat文件路径,选择apache-tomcat-8.5.63(8.5.63是我的版本号) 选择好路径后点ok就配置好了 总步骤:

代码随想录算法训练营第一天

● 今日学习的文章链接和视频链接 ● 自己看到题目的第一想法 1. 704二分法&#xff1a; 方法一&#xff1a; 整个数组是 左闭右闭区间 [ ] left指针指向数组开始下标&#xff0c; right 指针指向数组最后下表nums.size()-1, mid为 (leftright) /2循环条件 left<rightnu…

小折叠也能成为主力机,全新小折叠旗舰华为Pocket 2正式发布

2024年2月22日&#xff0c;华为在三亚举办华为Pocket 2时尚盛典&#xff0c;正式发布其全新小折叠旗舰华为Pocket 2。一直以来&#xff0c;华为致力于萃取各界艺术灵感&#xff0c;不断探寻科技美学的可能性&#xff0c;华为Pocket系列更是秉承将奢雅美学与尖端科技融为一体的理…

探索Redis是否为单线程的奥秘(文末送书)

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;数据结构、网络奇遇记 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. Redis中的多线程二. I/O多线程三. Redis中的多进程四. 结论五. 书籍推荐5.1 书…

第一个Qt程序中的秘密

创建第一个程序 首先我们打开Qt Creator 打开文件->New Projects... 菜单&#xff0c;创建我们的第一个Qt项目 选择 Qt Widgets Application&#xff0c;点击选择...按钮 之后&#xff0c;输入项目名称QtLearning&#xff0c;并选择创建路径&#xff0c; 在build system中选…

ConnectWise ScreenConnect 身份验证绕过漏洞复现可RCE(CVE-2024-1709)

0x01 产品简介 ConnectWise ScreenConnect ,是一款自托管的远程桌面软件应用,该款软件允许用户自行托管,可以在自己的服务器、个人电脑、虚拟机或虚拟专用服务器上运行。 0x02 漏洞概述 ConnectWise ScreenConnect低于23.9.8 版本的产品中,SetupWizard.aspx接口处存在身…

[newstarctf2023] --RE wp

AndroGenshin: rc4加密表&#xff0c;base64换表&#xff1a; 脚本梭就行 python username b"genshinimpact" base64_table [125, 239, 101, 151, 77, 163, 163, 110, 58, 230, 186, 206, 84, 84, 189, 193, 30, 63, 104, 178, 130, 211,164, 94, 75, 16, 32, 33…

发布 rust 源码包 (crates.io)

rust 编程语言的包 (或者 库, library) 叫做 crate, 也就是软件中的一个组件. 一个完整的软件通常由多个 crate 组成, rust 编译器 (rustc) 一次编译一整个 crate, 不同的 crate 可以同时并行编译. rust 官方有一个集中发布开源包的网站 crates.io. 发布在这上面的 crate 可以…

vue3框架组件自动导入unplugin-vue-components

1.安装 npm i unplugin-vue-components -save-dev 2.配置 我这里用的是Vue CLI&#xff0c;所以要在vue.config.js文件中添加配置&#xff0c;官网中有写不同打包工具的配置写法 框架我使用的是Element Plus&#xff0c;使用前去官网查看自己的框架是否支持&#xff0c;主流…

LLM之RAG实战(二十七)| 如何评估RAG系统

有没有想过今天的一些应用程序是如何看起来几乎神奇地智能的&#xff1f;这种魔力很大一部分来自于一种叫做RAG和LLM的东西。把RAG&#xff08;Retrieval Augmented Generation&#xff09;想象成人工智能世界里聪明的书呆子&#xff0c;它会挖掘大量信息&#xff0c;准确地找到…

电脑黑屏什么都不显示怎么办 电脑开机黑屏不显示任何东西的4种解决办法

相信有很多网友都有经历电脑开机黑屏不显示任何东西&#xff0c;找了很多方法都没处理好&#xff0c;其实关于这个的问题&#xff0c;首先还是要了解清楚开机黑屏的原因&#xff0c;才能够对症下药&#xff0c;下面大家可以跟小编一起来看看怎么解决吧 电脑开机黑屏不显示任何…

【无刷电机学习】基础概念及原理介绍(持续更新中...)

目录&#xff08;2024.02.22版&#xff09; 1 定义 2 各种电机优势比较 2.1 有刷与无刷比较 2.2 交流与直流比较 2.3 内转子与外转子比较 2.4 低压BLDC的一些优点 3 基本原理 3.1 单相无刷电机 3.2 三相无刷电机 4 驱动方法 4.1 六步换相控制 4.1.1 基本原理 4…

突发!AI独角兽「竹间智能」被曝停工停产6个月

大家好我是二狗。 今天早上起来刷朋友圈&#xff0c;看到一张截图——AI创企竹间智能&#xff0c;宣称因为公司所处的经营环境艰难&#xff0c;部分部门和岗位将从即日起停工停产6个月。 图源&#xff1a;&#xff08;企服科学&#xff09; 下面是文字版&#xff1a; 由于公司…

Linux网络编程(三-UDP协议)

目录 一、UDP概述 二、UDP的首部格式 三、UDP缓冲区 四、基于UDP的应用层协议 五、常见问题 一、UDP概述 UDP(User Datagram Protocol&#xff0c;用户数据协议报)是传输层协议&#xff0c;提供不可靠服务&#xff0c;其特点包括&#xff1a; 无连接&#xff1a;知道对端…

CSP-202309-3-梯度求解

CSP-202309-3-梯度求解 作为一个算法小白&#xff0c;本人第一次接触大模拟的题&#xff0c;本题的算法参考自&#xff1a;【CSP】202309-3 梯度求解 解题思路 1.输入处理 getchar();&#xff1a;从标准输入读取一个字符。这里它的作用可能是用来“吃掉”&#xff08;消耗&a…

Kafka_04_Topic和日志

Kafka_04_Topic和日志 Topic/PartitionTopicPartition 日志存储存储格式日志清理删除压缩 Topic/Partition Topic/Partition: Kafka中消息管理的基础单位 Topic和Partition并不实际存在(仅逻辑上的概念) 如: Topic和Partition关系 // 每个日志文件可对应多个日志分段, 其还可…