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. SpringMVC01:入门、请求参数绑定、自定义类型转换器、常见注解

    一.介绍--三层架构和MVC 1.三层架构介绍和MVC设计模型介绍 开发架构一般都是基于两种形式,一种是 C/S 架构,也就是客户端/服务器,另一种是 B/S 架构,也就是浏览器/服务器.在 Java ...

  2. 【论文解读】NIPS 2021-HSWA: Hierarchical Semantic-Visual Adaption for Zero-Shot Learning.(基于层次适应的零样本学习)

    作者:陈使明 华中科技大学

  3. python软件开发目录规范

    软件开发目录规范 1.文件及目录的名字可以变换 但是思想是不变的 分类管理 2.目录规范主要规定开发程序的过程中针对不同的文件功能需要做不同的分类 myproject项目文件夹 1,bin文件夹 -- ...

  4. 前端内容(HTML CSS javaScript)

    前端内容 前端基础之HTML 前端基础之HTML HTML标签使用 HTML之form表单 前端基础之CSS 前端基础之CSS CSS字体颜色 背景 盒子模型 CSS浮动 溢出 头像框 CSS定位 i ...

  5. Python免杀过360

    本文章仅供参考学习 作者:mantou 博客地址:https://www.cnblogs.com/mantou0/ 分离免杀 这个我就不多说了,效果确实不错,网上关于分离免杀的也有很多文章 不分离过3 ...

  6. python Flask 操作数据库

    Flask数据库 转载:Flask数据库 - 苦行僧95 - 博客园 (cnblogs.com) Flask-SQLAlchemy Flask-SQLAlchemy是在Flask中操作关系型数据库的拓 ...

  7. 学习.NET MAUI Blazor(一)、Blazor是个啥?

    先把Blazor放一边,先来看看目前Web开发的技术栈. 注:上图只是为了说明问题,没有任何语言歧视! 这是目前最常用的前后端分离开发模式,这个开发模式需要配备前端工程师和后端工程师.当然了,全栈工程 ...

  8. 递归实现指数型枚举 (n个可选可不选)

    递归实现指数型枚举 从 1∼n 这 n 个整数中随机选取任意多个,输出所有可能的选择方案. 输入格式 输入一个整数 n. 输出格式 每行输出一种方案. 同一行内的数必须升序排列,相邻两个数用恰好 1 ...

  9. .NetCore下基于FreeRedis实现的Redis6.0客户端缓存之缓存键条件优雅过滤

    前言 众所周知内存缓存(MemoryCache)数据是从内存中获取,性能表现上是最优的,但是内存缓存有一个缺点就是不支持分布式,数据在各个部署节点上各存一份,每份缓存的过期时间不一致,会导致幻读等各种 ...

  10. Word 交叉引用 给参考文献、图片题注添加引用

    参考文献引用 假如想在红色[1]处添加引用,实现点击[1]跳到参考文献[1]. 首先需要将参考文献进行编号. 在需要插入引用的地方,选择插入-->交叉引用 点击插入 最后可以把[1]调成上标 上 ...