代码随想录算法训练营第18天 | 513.找树左下角的值, 112. 路径总和,113. 路径总和 ||,106.从中序与后序遍历序列构造二叉树

二叉树理论基础:

https://programmercarl.com/%E4%BA%8C%E5%8F%89%E6%A0%91%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE

513.找树左下角的值

题目链接:https://leetcode.cn/problems/find-bottom-left-tree-value/

思路:(递归法)

首先要是最后一行,然后是最左边的值。
可以使用前序遍历(当然中序,后序都可以,因为本题没有 中间节点的处理逻辑,只要左优先就行),保证优先左边搜索,然后记录深度最大的叶子节点,此时就是树的最后一行最左边的值。
记得用一个int型的变量用来记录最大深度。

class Solution {private int MAX_DEEP = -1;private int value = 0;public int findBottomLeftValue(TreeNode root) {traversal(root,0);return value;}public void traversal(TreeNode node ,int depth){if(node == null)   return ;// 遇到叶子结点更新最大深度if(node.left == null && node.right == null){if(depth > MAX_DEEP){value = node.val;MAX_DEEP = depth;}}traversal(node.left,depth+1);traversal(node.right,depth+1);}
}

112. 路径总和

题目连接:https://leetcode.cn/problems/path-sum/description/

思路:

这道题我们要遍历从根节点到叶子节点的路径看看总和是不是目标和。
可以使用深度优先遍历的方式(本题前中后序都可以,无所谓,因为中节点也没有处理逻辑)来遍历二叉树。
本题我们要找一条符合条件的路径,所以递归函数需要返回值,及时返回。
在这里插入图片描述图中可以看出,遍历的路线,并不要遍历整棵树,所以递归函数需要返回值,可以用boolean类型表示。
不要去累加然后判断是否等于目标和,那么代码比较麻烦,可以用递减,让计数器count初始为目标和,然后每次减去遍历路径节点上的数值。
如果最后count == 0,同时到了叶子节点的话,说明找到了目标和。
如果遍历到了叶子节点,count不为0,就是没找到。这里count,就直接用targetSum 来代替了。

class Solution {public boolean hasPathSum(TreeNode root, int targetSum) {if(root == null)return false;targetSum -= root.val;// 是叶子结点if(root.left == null && root.right == null)return targetSum == 0;if(root.left != null){boolean res = hasPathSum(root.left,targetSum) ;// 若存在某种情况,成立if(res)return true;}if(root.right != null){boolean res = hasPathSum(root.right,targetSum);if(res)return true;}return false;}}

113. 路径总和 ||

题目链接:https://leetcode.cn/problems/path-sum-ii/description/

思路:

113.路径总和ii要遍历整个树,找到所有路径,所以递归函数不要返回值!

class Solution {public List<List<Integer>> pathSum(TreeNode root, int targetSum) {List<List<Integer>> res = new ArrayList<>();if(root == null)return res;List<Integer> path = new LinkedList<>();traversal(root,targetSum,res,path);return res;}public void traversal(TreeNode node, int targetSum, List<List<Integer>> res, List<Integer>path){path.add(node.val);// 是否是叶子结点if(node.left == null && node.right == null){if(targetSum - node.val == 0){res.add(new ArrayList<>(path));}return ;}if(node.left != null){traversal(node.left,targetSum - node.val,res,path);path.remove(path.size()-1);}if(node.right != null){traversal(node.right,targetSum - node.val,res,path);path.remove(path.size()-1);}}
}

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

题目链接:https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/description/
类似题目:105.从前序与中序遍历序列构造二叉树

思路:

何根据两个顺序构造一个唯一的二叉树,相信理论知识大家应该都清楚,就是以 后序数组的最后一个元素为切割点,先切中序数组,根据中序数组,反过来再切后序数组。一层一层切下去,每次后序数组最后一个元素就是节点元素。
在这里插入图片描述
说到一层一层切割,就应该想到了递归。

来看一下一共分几步:

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

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

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

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

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

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

难点就是如何切割,以及边界值找不好很容易乱套。

在切割的过程中会产生四个区间,把握不好不变量的话,一会左闭右开,一会左闭右闭,必然乱套!

这里我们用的是左闭右开,中序数组比较好切割,根据后序遍历的最后一个元素来切割就行。

重点是后序数组的切割,首先最后一个元素肯定是不要了,这里我们可以根据中序数组切成的左中序数组和右中序数组,那么后序数组就可以按照左中序数组的大小来切割,切成左后序数组和右后序数组。

接下来可以递归了,然后代码也就出来了。

class Solution {public TreeNode buildTree(int[] inorder, int[] postorder) {if(postorder.length == 0 || inorder.length == 0)return null;return buildHelper(inorder,0,inorder.length,postorder,0,postorder.length);}public TreeNode buildHelper(int[] inorder,int inorderStart, int inorderEnd,int[] postorder,int postorderStart, int postorderEnd){if(postorderStart == postorderEnd)return null;// 根节点int rootVal = postorder[postorderEnd -1];TreeNode root = new TreeNode(rootVal);// 中序遍历中的根节点int middleIndex;for(middleIndex = inorderStart; middleIndex < inorderEnd; middleIndex++){if(inorder[middleIndex] == rootVal)break;}// 切割中序数组// 中序左区间,左闭右开 [leftInorderStart, leftInorderEnd)int leftInorderStart = inorderStart;int leftInorderEnd = middleIndex;// 中序右区间,左闭右开 [rightInorderStart, rightInorderEnd)int rightInorderStart = middleIndex + 1;int rightInorderEnd = inorderEnd;// 切割后序数组// 后序左区间,左闭右开[leftPostorderStart, leftPostorderEnd)int leftPostorderStart = postorderStart;int leftPostorderEnd = postorderStart + (middleIndex - inorderStart);// 后序右区间,左闭右开int rightPostorderStart = leftPostorderEnd;int rightPostorderEnd = postorderEnd - 1;// System.out.println(rightPostorderStart+" "+rightPostorderEnd);root.left = buildHelper(inorder,leftInorderStart,leftInorderEnd,postorder,leftPostorderStart,leftPostorderEnd);root.right = buildHelper(inorder,rightInorderStart,rightInorderEnd,postorder,rightPostorderStart,rightPostorderEnd);return root;}
}

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

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

相关文章

【算法与数据结构】647、516、LeetCode回文子串+最长回文子序列

文章目录 一、647、回文子串二、516、最长回文子序列三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、647、回文子串 思路分析&#xff1a;判断一个字符串是否为回文串那么必须确定回文串的所在区间&#xff0c;而一维…

Quartus IP 之mif与hex文件创建与使用

一、mif与hex概述 ROM IP的数据需要满足断电不丢失的要求&#xff0c;ROM IP数据的文件格式一般有三种文件格式&#xff1a;.mif、.hex、.coe&#xff0c;Xilinx与Intel Altera支持的ROM IP数据文件格式如下&#xff1a; Xilinx与Altera支持的ROM文件格式 Alterahex、mifAM&am…

Java实现婚恋交友网站 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 会员管理模块2.3 新闻管理模块2.4 相亲大会管理模块2.5 留言管理模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 会员信息表3.2.2 新闻表3.2.3 相亲大会表3.2.4 留言表 四、系统展示五、核心代码5.…

2.4日总结

第一题&#xff1a;选数 题解&#xff1a;思路还是很简单的&#xff0c;只需要想清楚dfs里的函数都是什么就可以了&#xff0c;还有一个简单的判断素数的函数&#xff0c;这题真没啥难度&#xff0c;就是属于基础题吧&#xff0c;请看AC代码 #include <stdio.h> #includ…

「Kafka」消费者篇

「Kafka」消费者篇 Kafka 消费方式 Kafka 消费者工作流程 消费者总体工作流程 新版本&#xff08;0.9之后&#xff09;的 offset 保存在 kafka 的 Topic 里&#xff0c;持久化到磁盘&#xff0c;可靠性有保障。 老版本&#xff08;0.9之前&#xff09;的 offset 保存在 Zook…

前端学习第4天

一、复合选择器 1.后代选择器 2.子代选择器 3.并集选择器 4.交集选择器 5.伪类选择器 1.伪类-超链接&#xff08;拓展&#xff09; 二、CSS特性 1.继承性 body放在style中 2.层叠性 3.优先级 属性 !important;&#xff08;最高优先级&#xff09; 1.优先级-叠加计算规则 2.em…

源码梳理(3)MybatisPlus启动流程

文章目录 1&#xff0c;MybatisPlus的使用示例2&#xff0c;BaseMapper方法的执行2,1 MybatisMapperProxy代理对象2.2 InvocationHandler接口&#xff08;JDK动态代理&#xff09;2.3 MapperMethodInvoker接口2.4 MybatisMapperMethod 3&#xff0c;SqlSession的执行流程3.1 Sq…

Java SPI 代码示例

Java Service Provider Interface 是JDK自带的服务提供者接口又叫服务发现机制更是一种面向接口的设计思想。即JDK本身提供接口类&#xff0c; 第三方实现其接口&#xff0c;并作为jar包或其他方式注入到其中&#xff0c; 在运行时会被JDK ServiceLoader 发现并加载&#xff0c…

力扣热门100题刷题笔记 - 10. 正则表达式匹配

力扣热门100题 - 10. 正则表达式匹配 题目链接&#xff1a;10. 正则表达式匹配 题目描述&#xff1a; 给你一个字符串 s 和一个字符规律 p&#xff0c;请你来实现一个支持 . 和 * 的正则表达式匹配。 . 匹配任意单个字符 * 匹配零个或多个前面的那一个元素 所谓匹配&#xff…

3.0 Hadoop 概念

本章着重介绍 Hadoop 中的概念和组成部分&#xff0c;属于理论章节。如果你比较着急可以跳过。但作者不建议跳过&#xff0c;因为它与后面的章节息息相关。 Hadoop 整体设计 Hadoop 框架是用于计算机集群大数据处理的框架&#xff0c;所以它必须是一个可以部署在多台计算机上…

Linux内存管理:(十二)Linux 5.0内核新增的反碎片优化

文章说明&#xff1a; Linux内核版本&#xff1a;5.0 架构&#xff1a;ARM64 参考资料及图片来源&#xff1a;《奔跑吧Linux内核》 Linux 5.0内核源码注释仓库地址&#xff1a; zhangzihengya/LinuxSourceCode_v5.0_study (github.com) 外碎片化发生时&#xff0c;页面分配…

2024-2-4-复习作业

源代码&#xff1a; #include <stdio.h> #include <stdlib.h> typedef int datatype; typedef struct Node {datatype data;struct Node *next;struct Node *prev; }*DoubleLinkList;DoubleLinkList create() {DoubleLinkList s(DoubleLinkList)malloc(sizeof(st…