当前位置: 首页 > news >正文

重生之我在代码随想录刷算法第十四天 | 513.找树左下角的值、112. 路径总和、106.从中序与后序遍历序列构造二叉树

参考文献链接:代码随想录

本人代码是Java版本的,如有别的版本需要请上代码随想录网站查看。

513.找树左下角的值

[力扣题目链接]

解题思路

该题目的意思就是找最深层的最左边的元素,所以其实我们用什么顺序遍历都行,因为没有中的处理逻辑,只需要左比右更靠前就行。

或者可以用迭代法层序遍历,这个方法十分简单。

递归法

首先有result保存结果,maxDepth保存的是当前最大的深度,当有更深的就替换,这样可以确保找到的是深度最大的。

class Solution {int result = 0;int maxDepth = Integer.MIN_VALUE;public int findBottomLeftValue(TreeNode root) {digui(root,0);return result;}//遍历传入当前元素和当前深度public void digui(TreeNode node,int depth){if(node.left == null && node.right == null){//终止条件是叶子节点,然后就判断深度是否最深if(depth > maxDepth){maxDepth = depth;result = node.val;}}//先左后右,当左边被保存为result时,深度也更新了,那么右边即使遍历也不会保存,因为深度不够。if(node.left != null){digui(node.left,depth + 1);}if(node.right != null){digui(node.right,depth + 1);}} 
}
迭代法层序遍历

层序遍历一层比一层深,所以我们只需要每次保存每一层的最左边节点即可,最后留下的就是最深最左的。

class Solution {public int findBottomLeftValue(TreeNode root) {int result = root.val;Queue<TreeNode> queue = new LinkedList<>();queue.offer(root);while(!queue.isEmpty()){int len = queue.size();int count = len;while(len-- > 0){TreeNode temp = queue.poll();if(count - 1 == len){result = temp.val;     }if(temp.left != null){queue.offer(temp.left);}if(temp.right != null){queue.offer(temp.right);}}}return result;}
}

112. 路径总和

112.路径总和

113.路径总和ii

解题思路

这两道题比较类似,就是递归求路径总和,但还要加上回溯这样才能把每种情况都找到,不然只递归的话就只有一条路径了

注意点
res.add(new LinkedList<>(path));

该代码中res是路径总和ii中保存总结果的List<List>

path是List

在添加时为什么要这样呢,如果直接res.add(path); 当path改变结果就会改变,对于我们这道题,path会进行回溯,我们为了保存到完整的结果,所以new LinkedList去保存它。

112.路径总和
class Solution {boolean flag = false;public boolean hasPathSum(TreeNode root, int targetSum) {if(root == null){return false;}path(root,0,targetSum);return flag;}public void path(TreeNode node,int pathSum,int targetSum){if(node.left == null && node.right == null){if(pathSum + node.val == targetSum){flag = true;}}if(node.left != null){path(node.left,pathSum + node.val,targetSum);}if(node.right != null){path(node.right,pathSum + node.val,targetSum);}}
}
113.路径总和ii
class Solution {public List<List<Integer>> pathSum(TreeNode root, int targetSum) {List<List<Integer>> res = new LinkedList<>();if (root == null) return res; // 非空判断List<Integer> path = new LinkedList<>();preorderdfs(root, targetSum, res, path);return res;}public void preorderdfs(TreeNode root, int targetsum, List<List<Integer>> res, List<Integer> path) {path.add(root.val);// 遇到了叶子节点if (root.left == null && root.right == null) {// 找到了和为 targetsum 的路径if (targetsum - root.val == 0) {res.add(new LinkedList<>(path));}return; // 如果和不为 targetsum,返回}if (root.left != null) {preorderdfs(root.left, targetsum - root.val, res, path);path.remove(path.size() - 1); // 回溯}if (root.right != null) {preorderdfs(root.right, targetsum - root.val, res, path);path.remove(path.size() - 1); // 回溯}}
}

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

力扣题目链接

解题思路
  • 中序遍历 inorder = [9,3,15,20,7]
  • 后序遍历 postorder = [9,15,7,20,3]

首先我们要知道根节点,后序遍历的最后一个节点就一定是根节点。是3

然后去中序遍历3可以分割数组为9和15 20 7。 9就是左,15 20 7就是右子树。

然后再去后序遍历,15 7 20,所以20是右子树的根节点。

综上,我们只需要递归一直分割两个数组即可。

代码示例
class Solution {public TreeNode buildTree(int[] inorder, int[] postorder) {if(inorder.length == 0 || postorder.length == 0){return null;}//从后序数组最后一位获取根节点int post = postorder[postorder.length - 1];TreeNode root = new TreeNode(post);int index = 0;//切分中序for(int i = 0;i < inorder.length;i++){if(post == inorder[i]){index = i;break;}}int[] inleft;if(index == 0){inleft = new int[0];}else{inleft = Arrays.copyOfRange(inorder,0,index);}int [] inright = Arrays.copyOfRange(inorder,index+1,inorder.length);//切分后序int[] postleft;int[] postright;if(index == 0){postleft = new int[0];postright = Arrays.copyOfRange(postorder,index,postorder.length-1);}else if(index == inorder.length - 1){postleft = Arrays.copyOfRange(postorder,0,inleft.length);postright = new int[0];}else{postleft = Arrays.copyOfRange(postorder,0,inleft.length);postright = Arrays.copyOfRange(postorder,inleft.length,postorder.length-1);}//继续递归左子树和右子树root.left = buildTree(inleft,postleft);root.right = buildTree(inright,postright);return root;}
}

相关文章:

  • mysql-connector-java本地试验
  • Python数据分析工具(三):pymssql的用法
  • 选对工具,效率飞跃提升
  • Kibana中突然看不到日志ElasticSearch突然采集不到日志问题解决分析
  • Ubuntu24.04 安装ssh开启22端口及允许root用户远程登录
  • 记录一次学习--委派攻击学习
  • Ubuntu以及ROS的一些方便设置及使用
  • H.264与H.265
  • Protobuf vs Thrift: 高性能序列化框架的对比与分析
  • 消息队列常见面试题总结
  • Linux复习--系统管理类(权限优化、备份策略、RAID、资源查看、启动流程、系统优化)
  • 灵当CRM index.php接口SQL注入漏洞复现 [附POC]
  • [uni-app]小兔鲜-02项目首页
  • 菱形继承、菱形虚拟继承、菱形继承中多态问题、菱形虚拟继承中多态问题
  • 2024外研社综合能力大赛第一场真题
  • 【跃迁之路】【641天】程序员高效学习方法论探索系列(实验阶段398-2018.11.14)...
  • export和import的用法总结
  • go append函数以及写入
  • HTTP那些事
  • React-Native - 收藏集 - 掘金
  • SpingCloudBus整合RabbitMQ
  • Yeoman_Bower_Grunt
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 大主子表关联的性能优化方法
  • 回流、重绘及其优化
  • 如何解决微信端直接跳WAP端
  • 通过git安装npm私有模块
  • 一起来学SpringBoot | 第十篇:使用Spring Cache集成Redis
  • 一些关于Rust在2019年的思考
  • 好程序员web前端教程分享CSS不同元素margin的计算 ...
  • 浅谈sql中的in与not in,exists与not exists的区别
  • 组复制官方翻译九、Group Replication Technical Details
  • # 深度解析 Socket 与 WebSocket:原理、区别与应用
  • # 手柄编程_北通阿修罗3动手评:一款兼具功能、操控性的电竞手柄
  • $.each()与$(selector).each()
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (2)Java 简介
  • (3) cmake编译多个cpp文件
  • (3)选择元素——(14)接触DOM元素(Accessing DOM elements)
  • (7)svelte 教程: Props(属性)
  • (Redis使用系列) Springboot 使用redis实现接口幂等性拦截 十一
  • (SpringBoot)第二章:Spring创建和使用
  • (STM32笔记)九、RCC时钟树与时钟 第二部分
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (附源码)计算机毕业设计SSM智慧停车系统
  • (转)项目管理杂谈-我所期望的新人
  • ****** 二十三 ******、软设笔记【数据库】-数据操作-常用关系操作、关系运算
  • .“空心村”成因分析及解决对策122344
  • .net core IResultFilter 的 OnResultExecuted和OnResultExecuting的区别
  • .NET Core 实现 Redis 批量查询指定格式的Key
  • .NET 通过系统影子账户实现权限维持
  • .NET牛人应该知道些什么(2):中级.NET开发人员
  • ;号自动换行
  • [ 环境搭建篇 ] 安装 java 环境并配置环境变量(附 JDK1.8 安装包)
  • [8] CUDA之向量点乘和矩阵乘法