【寸铁的刷题笔记】树、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;在有数据回调的开发场…

SQL查询每个类别价格前3的数据

SELECTproduct_id,category,price FROM (SELECTproduct_id,category,price,ROW_NUMBER() OVER (PARTITION BY category ORDER BY price) AS rankFROMyour_products_table ) AS ranked_products WHERErank < 3;DENSE_RANK() 和 ROW_NUMBER() 是窗口函数&#xff08;Window Fu…

前端知识复习

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就配置好了 总步骤:

Vue 图片轮播第三方库 Vue-awesome-swiper介绍及简单例子

vue-awesome-swiper 是一个基于 Swiper 的 Vue 轮播图组件&#xff0c;Swiper 是一个流行的移动端触摸滑动插件。它为 Vue.js 应用提供了一套丰富的轮播组件&#xff0c;支持多种布局和功能&#xff0c;如自动播放、无限循环、触摸滑动等。 安装 首先&#xff…

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

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

打开stable diffusion webui时,提示缺少clip或clip安装不上的解决方案(windows下的操作)

1.问题描述 打开stable diffusion webui时&#xff0c;提示缺少clip或clip安装不上 2.解决方案 原因&#xff1a;stable diffusion webui环境中的clip其实是open_clip&#xff0c;不能用pip install clip安装解决方法是直接到github下载 open_clip 代码到本地&#xff0c;并…

linux环境ssh-rsa进行签名\权限\登录\原理(免密登录)

linux环境ssh-rsa进行签名权限登录(免密登录) SSH原理与运用什么是SSH?SSH的使用场景ssh-rsa获取xshell环境登录获取ssh-rsa使用ssh-rsa登录SHA系列SHA-1、SHA-256和RSA的区别RSA原理数论基础RSA机制RSA数学密钥生成公式RSA数学加密理论RSA数学签名公式

小折叠也能成为主力机,全新小折叠旗舰华为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 书…

高效时间管理法则

你是否天天在忙&#xff0c;是否忙的不得要领&#xff0c;认真领会时间管理的四象限工作法&#xff0c;它会让你的工作变得高效。 目录 一、时间管理的误区 二、时间是如何被浪费的&#xff1f; 内部因素 外部因素 三、时间管理的5个阶段 1.公鸡型时间管理&#xff1a; …

第一个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接口处存在身…

Android14 InputManager-焦点窗口的更新

设置焦点时需要 先设置焦点APP mFo-cusedApp是一个AppWindowToken&#xff0c;在WMS中用来表示当前处于Resume状态的Activity。它是由AMS在开始启动一个Activity时调用WMS的setFocusedApp&#xff08;&#xff09;函数设置的。 考虑以下应用场景&#xff0c;当用户从Launche…

内存管理——线性内存,进程空间

低2G为进程空间 开始地址结束地址大小属性00xFFFFF1M保留0x1000000x102FFF栈不固定位置、大小0x1030000x143FFF堆不固定位置、大小0x400000主程序文件不固定位置、大小加载dll不固定位置、大小0x7ffdd000TIB位置&#xff0c;大小编译时固定0x7FFFE000系统与用户共享数据块位置…

[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 可以…

uniapp微信公众号H5分享

如果项目文件node_modules中没有weixin-js-sdk文件&#xff0c;则直接使用本文章提供的&#xff1b; 如果不生效&#xff0c;则在template.h5.html中引入 <script src"https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script> 首先引入weixin-js-…