题目
给定一棵树的前序遍历 preorder 与中序遍历 inorder。请构造二叉树并返回其根节点。
输入: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7] 输出: [3,9,20,null,null,15,7]
题解
回顾一下树的三种遍历:
根左右(先序) 左根右(中序) 左右根(后序)
题目给定我们前序preorder和中序inorder,且值不会重复;
- 通过前序,我们可以获得根preorder[0];
-
再在中序中找到根的index;
-
那么可以将preorder 与 inorder各分为两段;array.slice()方法为前闭后开;
- preorderLeft: [1,index + 1) ;preorderRight:[index+1,preorder.length)
- inorderLeft: [0,index) ;inorderRight:[index+1,preorder.length)
- 根 :preorder[0] 和 inorder[index] (preorder[0] === inorder[index] )
-
开始递归,并创建TreeNode;
-
判断退出条件,preorder.length==1时那么没有足够的长度进行slice()操作,那么slice()会返回一个空数组,那么我们可以判断preorder.length === 0 那么就返回null
代码如下
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {number[]} preorder
* @param {number[]} inorder
* @return {TreeNode}
*/
var buildTree = function(preorder, inorder) {
if(preorder === -1){
return -1 ;
}
if(preorder.length == 0){
return null
}
let index = inorder.indexOf(preorder[0]);
let preorderLeft = preorder.slice(1,index + 1);
let preorderRight = preorder.slice(index + 1,preorder.length);
let inorderLeft = inorder.slice(0,index);
let inorderRight = inorder.slice(index + 1 , inorder.length);
let left = buildTree(preorderLeft,inorderLeft);
let right = buildTree(preorderRight,inorderRight)
return new TreeNode(preorder[0],left,right)
};