Day18:LeedCode 513.找树左下角的值 112. 路径总和 106.从中序与后序遍历序列构造二叉树

513. 找树左下角的值

给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。

假设二叉树中至少有一个节点。

示例 1:

 

294aeaf8d4977d45482b128bbf718283.jpeg

输入: root = [2,1,3]
输出: 1

 思路:出该二叉树的 最底层 最左边 节点的值=找出深度最大第一个结点(左结点先遍历)

方法一:递归法

如何找出深度最大的结点:回溯法,设置两个全局遍历maxlen,result记录最长深度,结果

图解:

120171f6743f49e0b5505720e41921fa.png

递归三部曲:

1.确定返回值和参数的类型

用一个全局变量记录最长深度,result记录结果,递归函数无返回值,参数为int len(当前深度),和传入结点TreeNode cur;

2.确认终止条件:

我们采用左优先遍历 ,遇到叶节点则return,如果该叶节点是深度更大的结点,则更新result;

3.单层递归逻辑:

用回溯法计算每个结点的深度

代码参考:

class Solution {int maxlen=-1;int result=0;public int findBottomLeftValue(TreeNode root) {//本题结点个数至少为1个travelsal(root,1);return result;}void travelsal(TreeNode cur,int len){//   if(root==null)return;if(cur.left==null&&cur.right==null){if(len>maxlen){//找到第一个深度更大的结点则更新resultresult=cur.val;maxlen=len;}return;}if(cur.left!=null){travelsal(cur.left,len+1);}//回溯,下一结点深度+1//本节点深度不变if(cur.right!=null){travelsal(cur.right,len+1);}//回溯,下一结点深度+1}
}

方法二:迭代法,层序遍历找到最后一排的第一个结点

层序遍历模板:

Day15:二叉树层序遍历 LeedCode 102.二叉树的层序遍历 199二叉树的右视图 637.二叉树的层平均值 101.对称二叉树 226.翻转二叉树-CSDN博客

代码参考:

class Solution {int result=0;public int findBottomLeftValue(TreeNode root) {Queue<TreeNode> myQ=new LinkedList<>();TreeNode cur=root;myQ.offer(cur);while(!myQ.isEmpty()){int len=myQ.size();for(int i=0;i<len;i++){//每层的第一个元素用来更新resultTreeNode temp=myQ.poll();if(i==0)result=temp.val;if(temp.left!=null){myQ.offer(temp.left);}if(temp.right!=null){myQ.offer(temp.right);}}}return result;}
}

112. 路径总和

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

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

示例 1:

 

6d411da702ef84d2a39823f28cda4f43.jpeg

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

78c92f555024492faa375b7a807ec303.png

思路:用回溯法遍历所有路径

递归三部曲:

1.确定返回值和参数类型

返回一个boolean类型,参数为int sums(用targetSum依次减去路径上的值)和TreeNode cur(记录当前遍历到哪个结点)

因为targetSum不是全局变量,我们不能用sums==targetSum来判断是否找到路径,用targetSum依次减去路径上的值,sums==0代表找到

2.确定终止条件

遇到叶子结点判断sums是否等于0

 if(cur.left==null&&cur.right==null&&sums==0){return true;}
 if(cur.left==null&&cur.right==null)return false;

3.确定单层递归逻辑:

找到了就立即返回false,没找到就找其他路径,当所有路径都遍历完时,返回false

 if(cur.left!=null){
            if(travelsal(cur.left,sums-cur.left.val))return true;
        }
if(cur.right!=null){
            if(travelsal(cur.right,sums-cur.right.val))return true;
        }

class Solution {public boolean hasPathSum(TreeNode root, int targetSum) {if(root==null)return false;return travelsal(root,targetSum-root.val);}boolean travelsal(TreeNode cur,int sums){if(cur.left==null&&cur.right==null&&sums==0){return true;}if(cur.left==null&&cur.right==null)return false;if(cur.left!=null){if(travelsal(cur.left,sums-cur.left.val))return true;}if(cur.right!=null){if(travelsal(cur.right,sums-cur.right.val))return true;}//遍历完所有路径均没找到,返回falsereturn false;}
}

方法二:迭代法

用栈来模拟回溯的过程:

1ebd3e6f285e4702bacc6d72124fef9d.png

思路:用一个栈放入所有分支路径,一个栈放入这些路径的总和值

class Solution {public boolean hasPathSum(TreeNode root, int targetSum) {if(root==null)return false;Stack<TreeNode> stack1=new Stack<>();Stack<Integer> stack2=new Stack<>();stack1.push(root);stack2.push(root.val);while(!stack1.empty()){TreeNode cur=stack1.pop();Integer curSum=stack2.pop();//如果该节点为叶节点,且路径值==target 返回true;if(cur.left==null&&cur.right==null&&curSum==targetSum)return true;if(cur.left!=null){stack1.push(cur.left);stack2.push(curSum+cur.left.val);}if(cur.right!=null){stack1.push(cur.right);stack2.push(curSum+cur.right.val);}}return false;}
}

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

给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

示例 1:

 

42699c3c8a4d858737d7b228e5185049.jpeg

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

4ae7bc1127244856b6fbf1975c737e5f.png

 思路:

  • 第一步:如果数组大小为零的话,说明是空节点了。

  • 第二步:如果不为空,那么取后序数组最后一个元素作为节点元素。

  • 第三步:找到后序数组最后一个元素在中序数组的位置,作为切割点

  • 第四步:切割中序数组,切成中序左数组和中序右数组 (顺序别搞反了,一定是先切中序数组)

  • 第五步:切割后序数组,切成后序左数组和后序右数组

  • 第六步:递归处理左区间和右区间

图解:

a2d59669b3f14e60bb2ee4bee3af1c76.png

 

代码:

class Solution {public TreeNode buildTree(int[] inorder, int[] postorder) {if(inorder.length==0)return null;//根据后序遍历找到根节点int rootValue=postorder[postorder.length-1];TreeNode root=new TreeNode(rootValue);//在中序遍历中找到根节点的位置int index=0;for(int i=0;i<inorder.length;i++){if(inorder[i]==rootValue) index=i;}//切割中序数组,中序数组在rootValue左边的值是左子树,在rootValue右边的值是右子树int[] left_inorder=Arrays.copyOfRange(inorder,0,index);int[] right_inorder=Arrays.copyOfRange(inorder,index+1,inorder.length);//切割后序数组int[] left_postorder=Arrays.copyOfRange(postorder,0,index);int[] right_postorder=Arrays.copyOfRange(postorder,index,postorder.length-1);root.left=buildTree(left_inorder,left_postorder);root.right=buildTree(right_inorder,right_postorder);return root;}
}

 注意:Arrays.copyOfRange()主要用于对一个已有的数组进行截取复制,复制出一个左闭右开区间的数组。

相似题目:

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

给定两个整数数组 preorder 和 inorder ,其中 preorder 是二叉树的先序遍历, inorder 是同一棵树的中序遍历,请构造二叉树并返回其根节点。

 

示例 1:

 

042faf54261265f6eea664bcae95c621.jpeg

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

4ce108db8017420380cf1a05d4ef0e6a.png

代码:

class Solution {public TreeNode buildTree(int[] preorder, int[] inorder) {if(inorder.length==0)return null;//根据先序遍历找到根节点int rootValue=preorder[0];TreeNode root=new TreeNode(rootValue);//在中序遍历中找到根节点的位置int index=0;for(int i=0;i<inorder.length;i++){if(inorder[i]==rootValue) index=i;}//切割中序数组,中序数组在rootValue左边的值是左子树,在rootValue右边的值是右子树int[] left_inorder=Arrays.copyOfRange(inorder,0,index);int[] right_inorder=Arrays.copyOfRange(inorder,index+1,inorder.length);//切割先序序数组int[] left_preorder=Arrays.copyOfRange(preorder,1,1+index);int[] right_preorder=Arrays.copyOfRange(preorder,index+1,preorder.length);root.left=buildTree(left_preorder,left_inorder);root.right=buildTree(right_preorder,right_inorder);return root;}
}

 

 

 

 

 

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

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

相关文章

一个单生产-多消费模式下无锁方案(ygluu/卢益贵)

一个单生产-多消费模式下无锁方案 ygluu/卢益贵 关键词&#xff1a;生产者-消费者模型、无锁队列、golang、RWMutex 本文介绍一个“单生产(低频)-多消费”模式下的无锁哈希类方案&#xff0c;这个方案的性能优于golang的RWMutex&#xff0c;因为它永远不会因为“写”而导致与…

亚稳态及其解决办法

异步电路 亚稳态 亚稳态亚稳态的产生原因什么是同步异步信号怎么消除亚稳态 亚稳态 在数字电路中&#xff0c;每一位数据不是1&#xff08;高电平&#xff09;就是0&#xff08;低电平&#xff09;。当然对于具体的电路来说&#xff0c;并非1&#xff08;高电平&#xff09;就是…

Notepad++ 如何调整显示字面大小

在 Notepad 上&#xff0c;可以使用 ctrl 加上鼠标的左键来滚动来进行调整。 如何恢复默 可以使用 Ctrl 加数字键盘上的 / 键 来恢复默认设置。 当然也可以通过菜单栏上 view 菜单下的 Zoom 选项。 上面的界面中可以看到我们的在 Notepad 中使用的选项。 Notepad 如何调整显示…

Flutter开发进阶之瞧瞧BuildOwner

Flutter开发进阶之瞧瞧BuildOwner 上回说到关于Element Tree的构建还缺最后一块拼图&#xff0c;build的重要过程中会调用_element!.markNeedsBuild();&#xff0c;而markNeedsBuild会调用owner!.scheduleBuildFor(this);。 在Flutter框架中&#xff0c;BuildOwner负责管理构建…

计算机视觉之三维重建(2)---摄像机标定

文章目录 一、回顾线代1.1 线性方程组的解1.2 齐次线性方程组的解 二、透镜摄像机的标定2.1 标定过程2.2 提取摄像机参数2.3 参数总结 三、径向畸变的摄像机标定3.1 建模3.2 求解 四、变换4.1 2D平面上的欧式变换4.2 2D平面上的相似变换和仿射变换4.3 2D平面上的透射变换4.4 3D…

使用 VMWare 安装 Android-x86 系统(小白版)

文章目录 VMWare 介绍Android 系统介绍概述最终效果前置步骤开始安装 VMWare 介绍 VMware Workstation是VMware公司开发的一款桌面虚拟化软件。它允许用户在一台物理计算机上同时运行多个操作系统&#xff0c;每个操作系统都在自己的虚拟机中运行。这使得用户可以在同一台计算…

实例:NX二次开发使用链表进行拉伸功能(链表相关功能练习)

一、概述 在进行批量操作时经常会利用链表进行存放相应特征的TAG值&#xff0c;以便后续操作&#xff0c;最常见的就是拉伸功能。这里我们以拉伸功能为例子进行说明。 二、常用链表相关函数 UF_MODL_create_list 创建一个链表&#xff0c;并返回链表的头指针。…

认识String类

认识String类 前面我们学习了类和对象&#xff0c;这一小节咱们来谈String类 目录 认识String类前言一、String类的创建方式二、String引用类型的特点及方法1.存储内容2.String对象的比较3.字符串查找在这里插入图片描述4.转换&#xff08;一&#xff09;数字转为为字符串&…

阿里云原生:如何熟悉一个系统

原文地址:https://mp.weixin.qq.com/s/J8eK-qRMkmHEQZ_dVts9aQ?poc_tokenHMA-_mWjfcDmGVW6hXX1xEDDvuJPE3pL9-8uSlyY 导读&#xff1a;本文总结了熟悉系统主要分三部分&#xff1a;业务学习、技术学习、实战。每部分会梳理一些在学习过程中需要解答的问题&#xff0c;这些问题…

集成学习 | 集成学习思想:Stacking思想

目录 一. Stacking 思想 一. Stacking 思想 Stacking(或stacked generalization)&#xff0c;是指训练一个模型用于组合(combine)其他各个模型 Stacking有两层第一层是不同的基学习器&#xff08;classifiers/regressors&#xff09;第二层是用于组合基学习器的元学习&#xf…

Reactor Netty

在springframework 里面&#xff0c;我们只有connection id。但是在底层的reactor netty,我们除了connection id还有local address and remote address HTTP/1 HTTP/2

Qt creator构建DLL库

文章目录 一、构建DLL库二、隐式调用DLL库 一、构建DLL库 Qt creator创建DLL项目。 实现功能函数。 运行代码&#xff0c;debug目录下会有.dll和.lib文件。 二、隐式调用DLL库 QT新建控制台项目。将.lib文件和与之关联的头文件赋值到项目文件夹。 3. 添加头文件和外部依赖库…

GuLi商城-商品服务-API-三级分类-网关统一配置跨域

参考文档&#xff1a; https://tangzhi.blog.csdn.net/article/details/126754515 https://github.com/OYCodeSite/gulimall-learning/blob/master/docs/%E8%B0%B7%E7%B2%92%E5%95%86%E5%9F%8E%E2%80%94%E5%88%86%E5%B8%83%E5%BC%8F%E5%9F%BA%E7%A1%80.md 谷粒商城-day04-完…

[数据结构初阶]二叉树

各位读者老爷好&#xff0c;鼠鼠我现在浅浅介绍一些关于二叉树的知识点&#xff0c;在各位老爷茶余饭后的闲暇时光不妨看看&#xff0c;鼠鼠很希望得到各位老爷的指正捏&#xff01; 开始介绍之前&#xff0c;给各位老爷看一张风景照&#xff0c;有读者老爷知道在哪里吗&#x…

003- AutoCoder 使用Web版大模型,性感的Human As Model 模式

这是下面这篇文章的继续。 002- 用 AutoCoder 添加和修改代码 前面我们提到&#xff0c;如何解决你没有API版大模型&#xff0c;或者你的API版大模型太弱&#xff0c;而你只有Web版本的诸如 Kimi/GPT4 的情况下&#xff0c;改如何让AutoCoder帮助你完成编程&#xff1f; 我们有…

Excel数字乱码怎么回事 Excel数字乱码怎么调回来

在日常工作中&#xff0c;Excel是我们最常使用的数据处理软件之一&#xff0c;它强大的功能使得数据处理变得既简单又高效。然而&#xff0c;用户在使用Excel时偶尔会遇到数字显示为乱码的问题&#xff0c;这不仅影响了数据的阅读&#xff0c;也大大降低了工作效率。那么&#…

会员中心微服务

文章目录 1.环境配置1.创建会员中心模块2.检查父子模块的pom.xml1.父模块注意&#xff1a;如果父模块中的依赖显示not found&#xff0c;原因是子模块并没有引用&#xff0c;不用在意 2.子模块 3.pom.xml 引入相关依赖&#xff08;别忘记刷新maven&#xff09;4.application.ym…

【Node.js】全局变量和全局 API

node 环境中没有 dom 和 bom &#xff0c;此外 es 基本上都是可以正常使用的。 如果一定要使用 dom 和bom&#xff0c;可以借助第三方库 jsdom 帮助我们实现操作。npm i jsdom 实例&#xff1a; const fs require(node:fs) const {JSDOM} require(jsdom)const dom new JS…

scrapy爬虫框架

scrapy爬虫框架 一、scrapy的概念作用和工作流程1、scrapy的概念2、scrapy框架的作用3、scrapy的工作流程&#xff08;重点&#xff09;3.1 回顾之前的爬虫流程3.2 改写上述流程3.3 scrapy的流程3.4 scrapy的三个内置对象3.5 scrapy中每个模块的具体作用 二、scrapy的入门使用1…

Spring Boot1

SpringBoot概述 Spring Boot是Spring提供的一个子项目&#xff0c;用于快速构建Spring应用程序 SpringBoot特性 起步依赖 本质上就是一个Maven坐标&#xff0c;整合了完成一个功能所需要的所有坐标 自动配置 遵循约定大于配置的原则&#xff0c;再boot程序启动后&#xff0…