[Leedcode][JAVA][第105题][从前序与中序遍历序列构造二叉树][栈][递归][二叉树]
【问题描述】[中等]
根据一棵树的前序遍历与中序遍历构造二叉树。注意:
你可以假设树中没有重复的元素。例如,给出前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:3/ \9 20/ \15 7
【解答思路】
1. 递归
先序遍历的顺序是根节点,左子树,右子树。中序遍历的顺序是左子树,根节点,右子树。
只需要根据先序遍历得到根节点,然后在中序遍历中找到根节点的位置,它的左边就是左子树的节点,右边就是右子树的节点。
时间复杂度:O(N) 空间复杂度:O(N)
public TreeNode buildTree(int[] preorder, int[] inorder) {return buildTreeHelper(preorder, 0, preorder.length, inorder, 0, inorder.length);
}private TreeNode buildTreeHelper(int[] preorder, int p_start, int p_end, int[] inorder, int i_start, int i_end) {// preorder 为空,直接返回 nullif (p_start == p_end) {return null;}int root_val = preorder[p_start];TreeNode root = new TreeNode(root_val);//在中序遍历中找到根节点的位置int i_root_index = 0;for (int i = i_start; i < i_end; i++) {if (root_val == inorder[i]) {i_root_index = i;break;}}int leftNum = i_root_index - i_start;//递归的构造左子树root.left = buildTreeHelper(preorder, p_start + 1, p_start + leftNum + 1, inorder, i_start, i_root_index);//递归的构造右子树root.right = buildTreeHelper(preorder, p_start + leftNum + 1, p_end, inorder, i_root_index + 1, i_end);return root;
}
HashMap优化
public TreeNode buildTree(int[] preorder, int[] inorder) {HashMap<Integer, Integer> map = new HashMap<>();for (int i = 0; i < inorder.length; i++) {map.put(inorder[i], i);}return buildTreeHelper(preorder, 0, preorder.length, inorder, 0, inorder.length, map);
}private TreeNode buildTreeHelper(int[] preorder, int p_start, int p_end, int[] inorder, int i_start, int i_end,HashMap<Integer, Integer> map) {if (p_start == p_end) {return null;}int root_val = preorder[p_start];TreeNode root = new TreeNode(root_val);int i_root_index = map.get(root_val);int leftNum = i_root_index - i_start;root.left = buildTreeHelper(preorder, p_start + 1, p_start + leftNum + 1, inorder, i_start, i_root_index, map);root.right = buildTreeHelper(preorder, p_start + leftNum + 1, p_end, inorder, i_root_index + 1, i_end, map);return root;
}
2. 迭代 栈
用一个栈保存已经遍历过的节点,遍历前序遍历的数组,一直作为当前根节点的左子树,直到当前节点和中序遍历的数组的节点相等了,那么我们正序遍历中序遍历的数组,倒着遍历已经遍历过的根节点(用栈的 pop 实现),找到最后一次相等的位置,把它作为该节点的右子树。
代码细节
- 用一个栈保存已经遍历的节点
- 用 curRoot 保存当前正在遍历的节点
时间复杂度:O(N) 空间复杂度:O(N)
public TreeNode buildTree(int[] preorder, int[] inorder) {if (preorder.length == 0) {return null;}Stack<TreeNode> roots = new Stack<TreeNode>();int pre = 0;int in = 0;//先序遍历第一个值作为根节点TreeNode curRoot = new TreeNode(preorder[pre]);TreeNode root = curRoot;roots.push(curRoot);pre++;//遍历前序遍历的数组while (pre < preorder.length) {//出现了当前节点的值和中序遍历数组的值相等,寻找是谁的右子树if (curRoot.val == inorder[in]) {//每次进行出栈,实现倒着遍历while (!roots.isEmpty() && roots.peek().val == inorder[in]) {curRoot = roots.peek();roots.pop();in++;}//设为当前的右孩子curRoot.right = new TreeNode(preorder[pre]);//更新 curRootcurRoot = curRoot.right;roots.push(curRoot);pre++;} else {//否则的话就一直作为左子树curRoot.left = new TreeNode(preorder[pre]);curRoot = curRoot.left;roots.push(curRoot);pre++;}}return root;
}
class Solution {public TreeNode buildTree(int[] preorder, int[] inorder) {if(preorder.length==0 || inorder.length==0) {return null;}//根据前序数组的第一个元素,就可以确定根节点TreeNode root = new TreeNode(preorder[0]);for(int i=0;i<preorder.length;++i) {//用preorder[0]去中序数组中查找对应的元素if(preorder[0]==inorder[i]) {//将前序数组分成左右两半,再将中序数组分成左右两半//之后递归的处理前序数组的左边部分和中序数组的左边部分//递归处理前序数组右边部分和中序数组右边部分int[] pre_left = Arrays.copyOfRange(preorder,1,i+1);int[] pre_right = Arrays.copyOfRange(preorder,i+1,preorder.length);int[] in_left = Arrays.copyOfRange(inorder,0,i);int[] in_right = Arrays.copyOfRange(inorder,i+1,inorder.length);root.left = buildTree(pre_left,in_left);root.right = buildTree(pre_right,in_right);break;}}return root;}
}作者:wang_ni_ma
链接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/solution/dong-hua-yan-shi-105-cong-qian-xu-yu-zhong-xu-bian/
【总结】
1.前中后序遍历变化的是[中]的位置,左到右的顺序不改变
- 前序遍历 中左右
- 中序遍历 左中右
- 后续遍历 左右中
2.还原二叉树 借助HashMap or copyOfRange
根据前序和后序遍历构造二叉树
[Leetcode][第889题][JAVA][根据前序和后序遍历构造二叉树][分治][递归]
前序+中序遍历可画出原二叉树
[Leedcode][JAVA][第105题][从前序与中序遍历序列构造二叉树][栈][递归][二叉树]
后续+中序遍历可画出原二叉树
[Leetcode][第106题][JAVA][ 从中序与后序遍历序列构造二叉树][分治][递归]
3. 多画图 写写写 遍历代码 手撕变量 大脑保持清醒
转载链接:https://leetcode-cn.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by–22/
[Leedcode][JAVA][第105题][从前序与中序遍历序列构造二叉树][栈][递归][二叉树]相关推荐
- 二叉树 中序遍历 python_LeetCode 105 树 从前序与中序遍历序列构造二叉树(Medium)
17(105) 从前序与中序遍历序列构造二叉树(Medium) 描述 根据一棵树的前序遍历与中序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 示例 例如,给出前序遍历 preorder = ...
- LeetCode 刷题之旅(2020.05.22)——105. 从前序与中序遍历序列构造二叉树(中)
LeetCode 刷题之旅(2020.05.22)--105. 从前序与中序遍历序列构造二叉树(中) 题目: 根据一棵树的前序遍历与中序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 例如, ...
- 刷题记录8---验证二叉搜索树+二叉树的层序遍历+从前序与中序遍历序列构造二叉树+二叉树展开为链表+二叉树的最近公共祖先
前言 所有题目均来自力扣题库中的hot 100,之所以要记录在这里,只是方便后续复习 98.验证二叉搜索树 题目: 给你一个二叉树的根节点 root ,判断其是否是一个有效的二叉搜索树. 有效 二叉搜 ...
- 【LeetCode】【HOT】105. 从前序与中序遍历序列构造二叉树(哈希表+递归)
[LeetCode][HOT]105. 从前序与中序遍历序列构造二叉树 文章目录 [LeetCode][HOT]105. 从前序与中序遍历序列构造二叉树 package hot;import java ...
- 【必拿下系列】106. 从中序与后序遍历序列构造二叉树105从前序与中序遍历序列构造二叉树
两题各自的链接放这里了: 链接: 106 链接: 105 106.从中序与后序遍历序列构造二叉树 如果你是不知道理论的,那就得仔细分析了, 举个例子: 输入:inorder = [9,3,15,20, ...
- 105从前序与中序遍历序列构造二叉树 106 从中序与后序遍历序列构造二叉树 (递归 + 哈希)
引言 这两道题主要是考察二叉树遍历的掌握,即由前序和中序推出原二叉树,由后序和中序推出原二叉树,这里先来说一下推导过程: 前序和中序 知道前序遍历和中序遍历,如何推原二叉树?(直接是结论,可以自行推导 ...
- 二叉树 中序遍历 python_leetcode No.105 从前序与中序遍历序列构造二叉树
题目链接: 从前序与中序遍历序列构造二叉树 - 力扣(LeetCode)leetcode-cn.com 题目描述: 根据一棵树的前序遍历与中序遍历构造二叉树,可以假设树中没有重复的元素. 示例: 前 ...
- 【LeetCode系列】从中序与后序遍历序列构造二叉树 从前序与中序遍历序列构造二叉树...
关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! 105. 从前序与中序遍历序列构造二叉树 根据一棵树的前序遍历与中序遍历构造二叉树 ...
- 找树左下角的值+路径总和+从前序和中序遍历序列构造二叉树(day18*)
这篇可以主要关注一下如何确定递归时是否需要返回值. LC513. 找树左下角的值 给定一个二叉树的根节点,请找出该二叉树的 最底层最左边 节点的值. 思路1 层序遍历 class Solution:d ...
最新文章
- 查询linux kafka安装目录,Linux下安装并(单节点)配置启动Kafka
- python解析库beautifulsoup_12_Python_解析库_BeautifulSoup的使用
- Grub2倒计时失效
- 一款java代码生成器(我受够了加班),走起!
- 传递对象_洮北区司法局矫正对象献爱心传递社会正能量
- android反射开启通知_Android中反射的简单应用
- C语言重点难点:与,或和异或
- 重磅推荐,计算机视觉开源周报20191003期
- mysql 交换空间_MySQL优化纪录
- 纽约人寿CEO加入NYDIG董事会
- Fresher玩深沉
- python的help()
- java如何画五角星_Java——绘制五角星
- svg图形计算、矩阵函数计算、图形点位绝对坐标计算
- 使用easyrsa来制作证书
- SVN出现红绿双向箭头原因
- 26、灭火系统中最不利点处洒水喷头的工作压力是多少
- usb驱动的基本结构和函数简介【转】
- 基于python计算包含贝塞尔函数的积分
- 测试开发面试题(1)