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. editorial 专栏

    社论 22.10.1 solution for pl_er 密码是我的名字的拼音 全小写无空格 社论 22.10.2 solution for Simu. 密码是联考密码 社论 22.10.4 sol ...

  2. 论文解读(PCL)《Probabilistic Contrastive Learning for Domain Adaptation》

    论文信息 论文标题:Probabilistic Contrastive Learning for Domain Adaptation论文作者:Junjie Li, Yixin Zhang, Zilei ...

  3. STM32基本定时器控制LED闪烁代码

    led.c #include "led.h" void LED_Config(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2P ...

  4. MS17-010漏洞复现(永恒之蓝)

    0x01:温馨提示 微软已于2017 年 发布MS17-010补丁,修复了"永恒之蓝"攻击的系统漏洞,一定要及时更新Windows系统补丁. 本次只是简易的复现MS17-010,成 ...

  5. C#应用程序配置文件(XML序列化) - 开源研究系列文章

    上次写了一个C#线程池及管理器的博文( C#开发的线程池和管理器 - 开源研究系列文章 ),收到了不小的浏览量,在此感谢各位网友的支持.这次将另一个功能放出来单独讲解:C#应用程序的配置文件,使用的是 ...

  6. python进阶之路8 字典、元组、集合内置方法 编码理论

    内容回顾 作业讲解 1.前期不熟练的情况下一定要先写注释 2.一定要仔细思考每一行代码的含义 3.自己不会的代码或者不熟练的代码一定要多敲多练 数据类型内置方法简介 所有的数据类型基本上都自带了一些操 ...

  7. Angularjs的工程化

    Angularjs的工程化 AMD规范和CMD规范 为什么需要模块化管理工具 在编写项目时可能需要加载很多js文件,若b.js依赖a.js,且a.js比b.js大很多,那么浏览器会让b.js等待a.j ...

  8. Spring Native打包本地镜像,无需通过Graal的maven插件buildtools

    简介 在文章<GraalVM和Spring Native尝鲜,一步步让Springboot启动飞起来,66ms完成启动>中,我们介绍了如何使用Spring Native和buildtool ...

  9. C#移除字符串中的不可见Unicode字符

    背景 最近发现某个数据采集的系统拿下来的数据,有些字段的JSON被莫名截断了,导致后续数据分析的时候解析JSON失败. 类似这样 {"title": "你好 或者这样,多 ...

  10. 行为型模式 - 观察者模式Observer

    学习而来,代码是自己敲的.也有些自己的理解在里边,有问题希望大家指出. 有一个大佬视频中提过一个案例,我觉得很棒:遥闻深巷中犬吠,边有妇人惊觉欠伸,其夫呓语.继而儿醒,大啼.夫亦醒. 模式的定义与特点 ...