LeetCode(105):重建二叉树

题目描述

LeetCode(105):重建二叉树

解题思路:递归

前序遍历:根节点->左子节点->右子节点

中序遍历:左子节点->根节点->右子节点

针对前序和中序遍历的特点,我们不难得出以下思路

在每一轮递归中:

1、用preorder的头部值 初始化当前的root节点

2、在传入的2个数组的基础上,划分出当前root的左子树的前序/中序遍历数组、以及右子树的前序/中序遍历数组

3、调用自身,将左子树和右子树挂载到当前root上

4、返回当前root


下面我们具体来看第2个步骤如何实现

我们可以利用js提供的 indexOf 数组方法,找出当前root在inorder数组中的位置(记为 rootIndex)

因此,在inorder数组中,左子树和右子树的inorder数组分别位于 rootIndex 的左边和右边

这样一来,我们就可以利用 js 提供的 slice 方法,在原数组的基础上进行切割,从而得到左右子树的前序/中序遍历数组


除此之外,我们还要考虑一些特殊的情况:

  • 传入的前序/中序遍历数组为空:返回空
  • 传入的前序/中序遍历数组长度为1:当前为叶子节点
  • rootIndex 等于 0 :当前root节点没有左子树
  • rootIndex + 1 等于 数组的长度 :当前 root节点没有右子树

代码实现(Javascript)

/**
 * Definition for a binary tree node.
 * function TreeNode(val) {
 *     this.val = val;
 *     this.left = this.right = null;
 * }
 */
/**
 * @param {number[]} preorder
 * @param {number[]} inorder
 * @return {TreeNode}
 */
var buildTree = function(preorder, inorder) {
    if(preorder.length===0 || inorder.length===0){
        return null
    }
    if(preorder.length === 1 && inorder.length === 1){//没有左右子树
        return new TreeNode(preorder[0])
    }
    
    var root=new TreeNode(preorder[0])
    let rootIndex=inorder.indexOf(root.val)

    if(rootIndex!==0){ // 有左子树
        var leftinorder=inorder.slice(0,rootIndex)

        if(rootIndex + 1 >= preorder.length){//有左子树,没有右子树
            var leftpreorder=preorder.slice(1)
            root.left = buildTree(leftpreorder, leftinorder)
            root.right= buildTree([],[])
        }else{ // 有左右子树
            var leftpreorder=preorder.slice(1,rootIndex+1)
            var rightinorder=inorder.slice(rootIndex+1)
            var rightpreorder=preorder.slice(rootIndex+1)

            root.left = buildTree(leftpreorder, leftinorder)
            root.right = buildTree(rightpreorder, rightinorder)
        }
    }else{ // 没有左子树
        var rightinorder=inorder.slice(rootIndex+1)
        var rightpreorder=preorder.slice(rootIndex+1)
        root.left = buildTree([],[])
        root.right = buildTree(rightpreorder, rightinorder)
    }
    

    return root
};