输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

例如,给出

前序遍历 preorder = [3,9,20,15,7]
中序遍历 inorder = [9,3,15,20,7]
返回如下的二叉树:

3
     / \
   9  20
       /  \
    15    7

限制:

0 <= 节点个数 <= 5000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

分析

二叉树遍历规律:

前序遍历:【根节点, 递归前序遍历左子树,递归前序遍历右子树】

中序遍历:【递归中序遍历左子树,根节点,递归中序遍历右子树】

发现前序遍历数组的第一个元素是根节点,中序遍历数组中以根节点作为枢轴(pivot)把左右子树分隔开来,这样可以在中序遍历的数组中获取左子树和右子树的长度,再在前序遍历数组根据左右子树各自的长度

切割出前序遍历数组中的对应的左子树和右子树数组,然后递归的寻找每个子树的根节点返回并作为左/右子节点赋给上一个节点,如下图所示:

递归执行第一遍:前序[3,9,20,15,7],中序[9,3,15,20,7],根节点为3,切分得到新的左子树前序[9]、中序[9],右子树前序[20,15,7]、中序[15,20,7]

树:3
      /  \ 
    ...   ...

递归执行第二遍:前序[9],中序[9],长度只有1,故根节点是9,返回根节点

树:3
      /  \
     9  ...

递归执行第三遍:前序[20,15,7],中序[15,20,7],根节点是20,切分得到新的左子树前序[15]、中序[15],右子树前序[7]、中序[7],返回根节点

树:3
      /  \
   9    20

递归执行第四遍:前序[15],中序[15],长度只有1,故根节点是15,返回根节点

树:3
      /  \
   9    20
         /
       15

递归执行第五遍:前序[7],中序[7],长度只有1,故根节点是7,返回根节点,结束

树:3
      /  \
   9    20
        /   \
     15    7

递归解法:

 1 /**
2 * Definition for a binary tree node.
3 * function TreeNode(val) {
4 * this.val = val;
5 * this.left = this.right = null;
6 * }
7 */
8 /**
9 * @param {number[]} preorder
10 * @param {number[]} inorder
11 * @return {TreeNode}
12 */
13 var buildTree = function(preorder, inorder) {
14 if(preorder.length===0||inorder.length===0) return null;
15 let root = new TreeNode(preorder[0]);
16 if(preorder.length===1) return root;
17 let index =inorder.findIndex(e => e === root.val);
18 root.left = buildTree(preorder.slice(1,index+1), inorder.slice(0,index));
19 root.right = buildTree(preorder.slice(index+1), inorder.slice(index+1));
20
21 return root;
22 };

迭代解法:

分析:

//TODO

实现:

var buildTree = function(preorder, inorder) {
if(preorder.length===0||inorder.length===0) return null;
let root = new TreeNode(preorder[0]);
let stack = [root];
let inorderIndex = 0;
let node;
for(let i=1, len = preorder.length; i<len; i++) {
let preorderVal = preorder[i];
node = stack[stack.length-1];
if(node.val !== inorder[inorderIndex]) {
node.left = new TreeNode(preorderVal);
stack.push(node.left);
}else{
while(stack.length!==0 && stack[stack.length-1].val===inorder[inorderIndex]){
node = stack.pop();
inorderIndex++;
}
node.right = new TreeNode(preorderVal);
stack.push(node.right);
}
} return root;
};

最新文章

  1. 马里奥AI实现方式探索 ——神经网络+增强学习
  2. edittext把软键盘上的回车键改为搜索、发送或者 下一步,窗口随软键盘弹出而改变。
  3. OpenResty(nginx+lua) 入门
  4. 从走出校门到Java实习生生活
  5. tomcat部署到根路径
  6. jj前端项目1th总结
  7. #maven解决乱码问题
  8. VirtualBox虚拟机安装MSDOS和MINIX2.0.0双系统
  9. css3学习笔记之2D转换
  10. C primer plus 读书笔记第十二章
  11. linux awk命令详解2
  12. Git 分支 - 分支的衍合
  13. jquery给img添加按钮事件
  14. java中构造方法和this,static关键字
  15. java操作DBF的使用
  16. Java起源
  17. 虚拟机JVM
  18. 多端统一框架尝试--Taro
  19. R语言学习——输入与输出
  20. 开发中常遇到的Python陷阱和注意点-乾颐堂

热门文章

  1. Moonraker
  2. Linux安装PHP8 新版笔记
  3. ABP微服务系列学习-搭建自己的微服务结构(三)
  4. 溢出标志位OF与进位标志位CF判断
  5. python数据方面的文章
  6. K8s集群版本升级
  7. Markdown格式文档图片设置居右
  8. CSS:布局篇_用flex布局实现两边顶宽中间自适应(圣杯布局&amp;双飞翼布局)
  9. element-ui动态表单验证
  10. spring RedisTemplate用法