代码随想录-算法训练营day18【二叉树05:找树左下角的值、路径总和、从中序与后序遍历序列构造二叉树】

本文主要是介绍代码随想录-算法训练营day18【二叉树05:找树左下角的值、路径总和、从中序与后序遍历序列构造二叉树】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

代码随想录-035期-算法训练营【博客笔记汇总表】-CSDN博客

第六章 二叉树 part05今日内容 ● 513.找树左下角的值
● 112. 路径总和  113.路径总和ii
● 106.从中序与后序遍历序列构造二叉树 105.从前序与中序遍历序列构造二叉树详细布置 找树左下角的值  本地递归偏难,反而迭代简单属于模板题, 两种方法掌握一下 题目链接/文章讲解/视频讲解:https://programmercarl.com/0513.%E6%89%BE%E6%A0%91%E5%B7%A6%E4%B8%8B%E8%A7%92%E7%9A%84%E5%80%BC.html  路径总和  本题 又一次设计要回溯的过程,而且回溯的过程隐藏的还挺深,建议先看视频来理解 112. 路径总和,和 113. 路径总和ii 一起做了。 优先掌握递归法。题目链接/文章讲解/视频讲解:https://programmercarl.com/0112.%E8%B7%AF%E5%BE%84%E6%80%BB%E5%92%8C.html  从中序与后序遍历序列构造二叉树 本题算是比较难的二叉树题目了,大家先看视频来理解。 106.从中序与后序遍历序列构造二叉树,105.从前序与中序遍历序列构造二叉树 一起做,思路一样的题目链接/文章讲解/视频讲解:https://programmercarl.com/0106.%E4%BB%8E%E4%B8%AD%E5%BA%8F%E4%B8%8E%E5%90%8E%E5%BA%8F%E9%81%8D%E5%8E%86%E5%BA%8F%E5%88%97%E6%9E%84%E9%80%A0%E4%BA%8C%E5%8F%89%E6%A0%91.html 往日任务
● day 1 任务以及具体安排:https://docs.qq.com/doc/DUG9UR2ZUc3BjRUdY  
● day 2 任务以及具体安排:https://docs.qq.com/doc/DUGRwWXNOVEpyaVpG  
● day 3 任务以及具体安排:https://docs.qq.com/doc/DUGdqYWNYeGhlaVR6 
● day 4 任务以及具体安排:https://docs.qq.com/doc/DUFNjYUxYRHRVWklp 
● day 5 周日休息
● day 6 任务以及具体安排:https://docs.qq.com/doc/DUEtFSGdreWRuR2p4 
● day 7 任务以及具体安排:https://docs.qq.com/doc/DUElCb1NyTVpXa0Jj 
● day 8 任务以及具体安排:https://docs.qq.com/doc/DUGdsY2JFaFhDRVZH 
● day 9 任务以及具体安排:https://docs.qq.com/doc/DUHVXSnZNaXpVUHN4 
● day 10 任务以及具体安排:https://docs.qq.com/doc/DUElqeHh3cndDbW1Q 
●day 11 任务以及具体安排:https://docs.qq.com/doc/DUHh6UE5hUUZOZUd0 
●day 12 周日休息 
●day 13 任务以及具体安排:https://docs.qq.com/doc/DUHNpa3F4b2dMUWJ3 
●day 14 任务以及具体安排:https://docs.qq.com/doc/DUHRtdXZZSWFkeGdE 
●day 15 任务以及具体安排:https://docs.qq.com/doc/DUHN0ZVJuRmVYeWNv 
●day 16 任务以及具体安排:https://docs.qq.com/doc/DUHBQRm1aSWR4T2NK 
●day 17 任务以及具体安排:https://docs.qq.com/doc/DUFpXY3hBZkpabWFY

目录

0513_找树左下角的值

0112_路径总和

0113_路径总和ii

0106_从中序与后序遍历序列构造二叉树

0105_从前序与中序遍历序列构造二叉树


0513_找树左下角的值

package com.question.solve.leetcode.programmerCarl2._07_binaryTrees;import java.util.Deque;
import java.util.LinkedList;public class _0513_找树左下角的值 {
}/*** 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 Solution0513 {public int findBottomLeftValue(TreeNode root) {//迭代法int res = 0;if (root == null) {return res;}Deque<TreeNode> deuqe = new LinkedList<>();deuqe.offer(root);while (!deuqe.isEmpty()) {int size = deuqe.size();for (int i = 0; i < size; i++) {TreeNode poll = deuqe.poll();if (i == 0) {res = poll.val;}if (poll.left != null) {deuqe.offer(poll.left);}if (poll.right != null) {deuqe.offer(poll.right);}}}return res;}
}class Solution0513_2 {//递归法private int Deep = -1;private int value = 0;public int findBottomLeftValue(TreeNode root) {value = root.val;findLeftValue(root, 0);return value;}private void findLeftValue(TreeNode root, int deep) {if (root == null) return;if (root.left == null && root.right == null) {if (deep > Deep) {value = root.val;Deep = deep;}}if (root.left != null) findLeftValue(root.left, deep + 1);if (root.right != null) findLeftValue(root.right, deep + 1);}
}

0112_路径总和

package com.question.solve.leetcode.programmerCarl2._07_binaryTrees;import java.util.ArrayList;
import java.util.Stack;public class _0112_路径总和 {
}/*** 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 Solution0112 {public boolean hasPathSum(TreeNode root, int targetSum) {ArrayList<Integer> paths = new ArrayList<>();Boolean flag = false; //使用 Boolean包装类 来存储flag的状态traversal(root, paths, targetSum, flag);//flag不能是基本数据类型,return flag; //简化返回逻辑,直接返回flag//        int[] flag = new int[1]; //使用长度为1的数组来存储flag的状态
//        //Integer flag = 0; //使用 Integer包装类 来存储flag的状态
//        //Boolean flag = false; //使用 Boolean包装类 来存储flag的状态
//        traversal(root, paths, targetSum, flag);
//        return flag[0] == 1; //简化返回逻辑}private void traversal(TreeNode root, ArrayList<Integer> paths, int targetSum, Boolean flag) {if (root == null || flag) { //如果 flag 已经为 true,则不再进行遍历return;}paths.add(root.val);if (root.left == null && root.right == null) {int sum = 0;for (int x : paths) {sum += x;}if (sum == targetSum) {flag = true;return;}}if (root.left != null) {traversal(root.left, paths, targetSum, flag);paths.remove(paths.size() - 1);}if (root.right != null) {traversal(root.right, paths, targetSum, flag);paths.remove(paths.size() - 1);}}
}class Solution0112_2 {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 left = haspathsum(root.left, targetsum);if (left) {      //已经找到return true;}}if (root.right != null) {boolean right = haspathsum(root.right, targetsum);if (right) {     //已经找到return true;}}return false;}public boolean haspathsum2(TreeNode root, int targetsum) {//lc112 简洁方法if (root == null) return false; //为空退出//叶子节点判断是否符合if (root.left == null && root.right == null) return root.val == targetsum;//求两侧分支的路径和return haspathsum2(root.left, targetsum - root.val) || haspathsum(root.right, targetsum - root.val);}
}class Solution0112_3 {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.isEmpty()) {int size = stack1.size();for (int i = 0; i < size; i++) {TreeNode node = stack1.pop();int sum = stack2.pop();//如果该节点是叶子节点了,同时该节点的路径数值等于sum,那么就返回trueif (node.left == null && node.right == null && sum == targetSum) {return true;}//右节点,压进去一个节点的时候,将该节点的路径数值也记录下来if (node.right != null) {stack1.push(node.right);stack2.push(sum + node.right.val);}//左节点,压进去一个节点的时候,将该节点的路径数值也记录下来if (node.left != null) {stack1.push(node.left);stack2.push(sum + node.left.val);}}}return false;}public boolean hasPathSum2(TreeNode root, int targetSum) {Stack<TreeNode> treeNodeStack = new Stack<>();Stack<Integer> sumStack = new Stack<>();if (root == null)return false;treeNodeStack.add(root);sumStack.add(root.val);while (!treeNodeStack.isEmpty()) {TreeNode curr = treeNodeStack.peek();int tempsum = sumStack.pop();if (curr != null) {treeNodeStack.pop();treeNodeStack.add(curr);treeNodeStack.add(null);sumStack.add(tempsum);if (curr.right != null) {treeNodeStack.add(curr.right);sumStack.add(tempsum + curr.right.val);}if (curr.left != null) {treeNodeStack.add(curr.left);sumStack.add(tempsum + curr.left.val);}} else {treeNodeStack.pop();TreeNode temp = treeNodeStack.pop();if (temp.left == null && temp.right == null && tempsum == targetSum)return true;}}return false;}
}

0113_路径总和ii

package com.question.solve.leetcode.programmerCarl2._07_binaryTrees;import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;public class _0113_路径总和II {
}/*** 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 Solution0113 {public List<List<Integer>> pathSum(TreeNode root, int targetSum) {List<List<Integer>> res = new ArrayList<>();if (root == null) {//非空判断return res;}List<Integer> paths = new ArrayList<>();traversal(root, targetSum, res, paths);return res;}private void traversal(TreeNode root, int targetSum, List<List<Integer>> res, List<Integer> paths) {if (root == null) {return;}paths.add(root.val);if (root.left == null && root.right == null) {int sum = paths.stream().mapToInt(Integer::intValue).sum();if (targetSum == sum) {res.add(new ArrayList<>(paths));}}if (root.left != null) {traversal(root.left, targetSum, res, paths);paths.remove(paths.size() - 1);}if (root.right != null) {traversal(root.right, targetSum, res, paths);paths.remove(paths.size() - 1);}}
}class Solution0113_2 {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<>();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) {//遇到了叶子节点if (targetsum - root.val == 0) {//找到了和为targetSum的路径res.add(new ArrayList<>(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); //回溯}}
}class Solution0113_3 {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;}private void travesal(TreeNode root, int count) {if (root == null) return;path.offer(root.val);count -= root.val;if (root.left == null && root.right == null && count == 0) {result.add(new LinkedList<>(path));}travesal(root.left, count);travesal(root.right, count);path.removeLast();//回溯}
}class Solution0113_4 {public List<List<Integer>> pathSum(TreeNode root, int targetSum) {//DFS统一迭代法List<List<Integer>> result = new ArrayList<>();Stack<TreeNode> nodeStack = new Stack<>();Stack<Integer> sumStack = new Stack<>();Stack<ArrayList<Integer>> pathStack = new Stack<>();if (root == null)return result;nodeStack.add(root);sumStack.add(root.val);pathStack.add(new ArrayList<>());while (!nodeStack.isEmpty()) {TreeNode currNode = nodeStack.peek();int currSum = sumStack.pop();ArrayList<Integer> currPath = pathStack.pop();if (currNode != null) {nodeStack.pop();nodeStack.add(currNode);nodeStack.add(null);sumStack.add(currSum);currPath.add(currNode.val);pathStack.add(new ArrayList(currPath));if (currNode.right != null) {nodeStack.add(currNode.right);sumStack.add(currSum + currNode.right.val);pathStack.add(new ArrayList(currPath));}if (currNode.left != null) {nodeStack.add(currNode.left);sumStack.add(currSum + currNode.left.val);pathStack.add(new ArrayList(currPath));}} else {nodeStack.pop();TreeNode temp = nodeStack.pop();if (temp.left == null && temp.right == null && currSum == targetSum)result.add(new ArrayList(currPath));}}return result;}
}

0106_从中序与后序遍历序列构造二叉树

package com.question.solve.leetcode.programmerCarl2._07_binaryTrees;import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;public class _0106_从中序与后序遍历序列构造二叉树 {
}/*** 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 Solution0106 {Map<Integer, Integer> map; //方便根据数值查找位置public TreeNode buildTree(int[] inorder, int[] postorder) {map = new HashMap<>();for (int i = 0; i < inorder.length; i++) { //用map保存中序序列的数值对应位置map.put(inorder[i], i);}return findNode(inorder, 0, inorder.length, postorder, 0, postorder.length);  // 前闭后开}public TreeNode findNode(int[] inorder, int inBegin, int inEnd, int[] postorder, int postBegin, int postEnd) {//参数里的范围都是前闭后开if (inBegin >= inEnd || postBegin >= postEnd) {  // 不满足左闭右开,说明没有元素,返回空树return null;}int rootIndex = map.get(postorder[postEnd - 1]);  // 找到后序遍历的最后一个元素在中序遍历中的位置TreeNode root = new TreeNode(inorder[rootIndex]);  // 构造结点int lenOfLeft = rootIndex - inBegin;  // 保存中序左子树个数,用来确定后序数列的个数root.left = findNode(inorder, inBegin, rootIndex,postorder, postBegin, postBegin + lenOfLeft);root.right = findNode(inorder, rootIndex + 1, inEnd,postorder, postBegin + lenOfLeft, postEnd - 1);return root;}
}class Solution0106_2 {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);}private 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;}int leftInorderStart = inorderStart;int leftInorderEnd = middleIndex;int rightInorderStart = middleIndex + 1;int rightInorderEnd = inorderEnd;int leftPostorderStart = postorderStart;int leftPostorderEnd = postorderStart + (middleIndex - inorderStart);int rightPostorderStart = leftPostorderEnd;int rightPostorderEnd = postorderEnd - 1;root.left = buildHelper(inorder, leftInorderStart, leftInorderEnd, postorder, leftPostorderStart, leftPostorderEnd);root.right = buildHelper(inorder, rightInorderStart, rightInorderEnd, postorder, rightPostorderStart, rightPostorderEnd);return root;}
}class Solution0106_3 {public TreeNode buildTree(int[] inorder, int[] postorder) {if (postorder == null || postorder.length == 0) {return null;}TreeNode root = new TreeNode(postorder[postorder.length - 1]);Deque<TreeNode> stack = new LinkedList<TreeNode>();stack.push(root);int inorderIndex = inorder.length - 1;for (int i = postorder.length - 2; i >= 0; i--) {int postorderVal = postorder[i];TreeNode node = stack.peek();if (node.val != inorder[inorderIndex]) {node.right = new TreeNode(postorderVal);stack.push(node.right);} else {while (!stack.isEmpty() && stack.peek().val == inorder[inorderIndex]) {node = stack.pop();inorderIndex--;}node.left = new TreeNode(postorderVal);stack.push(node.left);}}return root;}
}

0105_从前序与中序遍历序列构造二叉树

package com.question.solve.leetcode.programmerCarl2._07_binaryTrees;import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;public class _0105_从前序与中序遍历序列构造二叉树 {
}/*** 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 Solution0105 {Map<Integer, Integer> map;public TreeNode buildTree(int[] preorder, int[] inorder) {map = new HashMap<>();for (int i = 0; i < inorder.length; i++) {//用map保存中序序列的数值对应位置map.put(inorder[i], i);}return findNode(preorder, 0, preorder.length, inorder, 0, inorder.length); //前闭后开}public TreeNode findNode(int[] preorder, int preBegin, int preEnd, int[] inorder, int inBegin, int inEnd) {//参数里的范围都是前闭后开if (preBegin >= preEnd || inBegin >= inEnd) {//不满足左闭右开,说明没有元素,返回空树return null;}int rootIndex = map.get(preorder[preBegin]);  //找到前序遍历的第一个元素在中序遍历中的位置TreeNode root = new TreeNode(inorder[rootIndex]);  //构造结点int lenOfLeft = rootIndex - inBegin;  //保存中序左子树个数,用来确定前序数列的个数root.left = findNode(preorder, preBegin + 1, preBegin + lenOfLeft + 1,inorder, inBegin, rootIndex);root.right = findNode(preorder, preBegin + lenOfLeft + 1, preEnd,inorder, rootIndex + 1, inEnd);return root;}
}class Solution0105_2 {public TreeNode buildTree(int[] preorder, int[] inorder) {if (preorder == null || preorder.length == 0) {return null;}TreeNode root = new TreeNode(preorder[0]);Deque<TreeNode> stack = new LinkedList<TreeNode>();stack.push(root);int inorderIndex = 0;for (int i = 1; i < preorder.length; i++) {int preorderVal = preorder[i];TreeNode node = stack.peek();if (node.val != inorder[inorderIndex]) {node.left = new TreeNode(preorderVal);stack.push(node.left);} else {while (!stack.isEmpty() && stack.peek().val == inorder[inorderIndex]) {node = stack.pop();inorderIndex++;}node.right = new TreeNode(preorderVal);stack.push(node.right);}}return root;}
}

这篇关于代码随想录-算法训练营day18【二叉树05:找树左下角的值、路径总和、从中序与后序遍历序列构造二叉树】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/922248

相关文章

深入理解Mysql OnlineDDL的算法

《深入理解MysqlOnlineDDL的算法》本文主要介绍了讲解MysqlOnlineDDL的算法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小... 目录一、Online DDL 是什么?二、Online DDL 的三种主要算法2.1COPY(复制法)

Java集合之Iterator迭代器实现代码解析

《Java集合之Iterator迭代器实现代码解析》迭代器Iterator是Java集合框架中的一个核心接口,位于java.util包下,它定义了一种标准的元素访问机制,为各种集合类型提供了一种统一的... 目录一、什么是Iterator二、Iterator的核心方法三、基本使用示例四、Iterator的工

Java 线程池+分布式实现代码

《Java线程池+分布式实现代码》在Java开发中,池通过预先创建并管理一定数量的资源,避免频繁创建和销毁资源带来的性能开销,从而提高系统效率,:本文主要介绍Java线程池+分布式实现代码,需要... 目录1. 线程池1.1 自定义线程池实现1.1.1 线程池核心1.1.2 代码示例1.2 总结流程2. J

JS纯前端实现浏览器语音播报、朗读功能的完整代码

《JS纯前端实现浏览器语音播报、朗读功能的完整代码》在现代互联网的发展中,语音技术正逐渐成为改变用户体验的重要一环,下面:本文主要介绍JS纯前端实现浏览器语音播报、朗读功能的相关资料,文中通过代码... 目录一、朗读单条文本:① 语音自选参数,按钮控制语音:② 效果图:二、朗读多条文本:① 语音有默认值:②

Vue实现路由守卫的示例代码

《Vue实现路由守卫的示例代码》Vue路由守卫是控制页面导航的钩子函数,主要用于鉴权、数据预加载等场景,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一、概念二、类型三、实战一、概念路由守卫(Navigation Guards)本质上就是 在路

uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)

《uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)》在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题,下面:本文主要介绍uni-app小程序项目中实... 目录方式一:使用<canvas>实现图片压缩(推荐,兼容性好)示例代码(小程序平台):方式二:使用uni

JAVA实现Token自动续期机制的示例代码

《JAVA实现Token自动续期机制的示例代码》本文主要介绍了JAVA实现Token自动续期机制的示例代码,通过动态调整会话生命周期平衡安全性与用户体验,解决固定有效期Token带来的风险与不便,感兴... 目录1. 固定有效期Token的内在局限性2. 自动续期机制:兼顾安全与体验的解决方案3. 总结PS

利用Python把路径转为绝对路径的方法

《利用Python把路径转为绝对路径的方法》在Python中,如果你有一个相对路径并且想将其转换为绝对路径,你可以使用Path对象的resolve()方法,Path是Python标准库pathlib中... 目录1. os.path.abspath 是什么?怎么用?基本用法2. os.path.abspat

C#中通过Response.Headers设置自定义参数的代码示例

《C#中通过Response.Headers设置自定义参数的代码示例》:本文主要介绍C#中通过Response.Headers设置自定义响应头的方法,涵盖基础添加、安全校验、生产实践及调试技巧,强... 目录一、基础设置方法1. 直接添加自定义头2. 批量设置模式二、高级配置技巧1. 安全校验机制2. 类型

Python屏幕抓取和录制的详细代码示例

《Python屏幕抓取和录制的详细代码示例》随着现代计算机性能的提高和网络速度的加快,越来越多的用户需要对他们的屏幕进行录制,:本文主要介绍Python屏幕抓取和录制的相关资料,需要的朋友可以参考... 目录一、常用 python 屏幕抓取库二、pyautogui 截屏示例三、mss 高性能截图四、Pill