leetcode-105-从前序与中序遍历序列构造二叉树

299 阅读1分钟

image.png leetcode原题

解题思路

  • 前序遍历的顺序为根左右,中序遍历的顺序为左根右,所以 preorder[0] 为当前子树根节点的值

  • 查找该值在 inorder 中的位置,其左边即为左子树中序遍历序列,右边为右子树中序遍历序列

  • 获取到左右子树中序遍历后,因为子树前序遍历和中序遍历的结果只是顺序不同,但是序列长度是相同的,所以可以根据左子树中序遍历序列长度去 preorder 获取左子树前序遍历序列,剩余部分即为右子树前序遍历序列

  • 然后就可以通过根节点的值创建根节点,根据左右子树的前序、中序遍历序列递归创建左右子树

  • 最后返回二叉树的根节点即可

var buildTree = function(preorder, inorder) {
    let map = new Map();
    for(let i = 0; i < inorder.length; i++){
        map.set(inorder[i],i)
    }
    const helper = function(pStart, pEnd, iStart, iEnd){
        // 判断我们的前序遍历数组已经使用完毕
        if(pStart > pEnd) return null;
        // 获取根节点的值
        let rootVal = preorder[pStart];
        // 构造一个根节点
        let root = new TreeNode(rootVal);
        // 获取根节点在终须遍历数组中的索引位置,来分隔左右子树
        let mid = map.get(rootVal);
        // 计算左子树的节点个数,用来在前序遍历数组确定左子树结束的位置
        let leftNum = mid - iStart;
        // 递归的构建左子树
        root.left = helper(pStart + 1, pStart + leftNum, iStart,mid -1);
         // 递归的构建右子树
        root.right = helper(pStart + leftNum + 1, pEnd, mid + 1 , iEnd);
        return root;
    }
    return helper(0 , preorder.length -1, 0, inorder.length -1)
};