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. Java工厂模式的最佳实践?

    "Simplicity is prerequisite for reliability." - Edsger Dijkstra "简单是可靠的前提条件." -- ...

  2. DHorse日志收集原理

    实现原理 基于k8s的日志收集主要有两种方案,一是使用daemoset,另一种是基于sidecar.两种方式各有优缺点,目前DHorse是基于daemoset实现的.如图1所示: 图1 在每个k8s集 ...

  3. before-after-hook钩子函数

    before-after-hook 最近看别人的代码,接触到一个插件,before-after-hook,百度搜一圈也没有看到什么地方有教程,看这个字面意思是一个hook,和axios里面的拦截器,v ...

  4. nuxt.js框架 如何打包 build

    nuxt脚手架开发好项目后怎么打包 以下是脚手架的package.json部分代码 "scripts": { "dev": "cross-env NO ...

  5. HMS Core 3D流体仿真技术,打造移动端PC级流体动效

    移动设备硬件的高速发展,让游戏行业发生翻天覆地的变化,许多酷炫的游戏效果不再局限于电脑端,玩家在移动端就能享受到场景更逼真.画质更清晰.体验更流畅的游戏服务.但由于移动设备算力不足,为了实现真实感的水 ...

  6. day11-功能实现10

    家居网购项目实现010 以下皆为部分代码,详见 https://github.com/liyuelian/furniture_mall.git 24.bugFix-添加购物车按钮动态处理 24.1需求 ...

  7. 深入理解C++虚函数底层机制和RTTI运行时类型识别

    当调用一个虚函数时,被执行的代码必须与调用函数对象的动态类型相一致:指向对象的指针或引用的类型是不重要的,编译器是如何高效地提供这种行为呢?大多数编译器是使用virtual table和virtual ...

  8. 通过rpm安装postgresql-9.6无法远程连接的问题

    1.停止postgresql服务 service postgresql-9.6 stop 2.修改postgresql.conf vi /var/lib/pgsql/9.6/data/postgres ...

  9. Hugging Face 2023 实习生招募计划

    Hugging Face 2023 实习生招募计划 想参与到 <王婆卖瓜>「最酷的 AI 社区」</王婆卖瓜>,共同构建未来吗?今天,我们为大家分享 Hugging Face ...

  10. mysql常用命令,检查数据库连接情况以及修改时区

    常用操作 注:也可以运行 mysql -u 用户名(root) -p 密码(root) 数据库名(bank) ,然后回车 导入文件:source e:bank.sql (你的sql文件) 回车 PS ...