【刷题打卡】1008. 前序遍历构造二叉搜索树

125 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一、题目描述:

1008. 前序遍历构造二叉搜索树 - 力扣(LeetCode) (leetcode-cn.com)

给定一个整数数组,它表示BST(即 二叉搜索树 )的 先序遍历 ,构造树并返回其根。

保证 对于给定的测试用例,总是有可能找到具有给定需求的二叉搜索树。

二叉搜索树 是一棵二叉树,其中每个节点, Node.left 的任何后代的值 严格小于 Node.val , Node.right 的任何后代的值 严格大于 Node.val。

二叉树的 前序遍历 首先显示节点的值,然后遍历Node.left,最后遍历Node.right。

示例 1:

输入:preorder = [8,5,1,7,10,12]
输出:[8,5,10,1,7,null,12]

示例 2:

输入: preorder = [1,3]
输出: [1,null,3]

提示:

  • 1 <= preorder.length <= 100
  • 1 <= preorder[i] <= 10^8
  • preorder 中的值 互不相同

二、思路分析:

  1. 通过中序数组和前序数组可以确定一棵二叉树
  2. 二叉搜索树的中序遍历数组是一个递增数组
  3. 前序遍历的第一个值是根节点,通过根节点可以在中序遍历中拆分出左子树和右子树
  4. 根据拆分出来的左子树长度和右子树长度,可以确定前序遍历中那些节点属于左子树,哪些属于右子树
  5. 有了对应的左子树右子树的中序遍历数组和前序遍历数组,可以递归得到整个二叉树
  6. 当参数中的数组大小为空的时候,返回 null

三、AC 代码:

/**
 * @param {number[]} preorder
 * @return {TreeNode}
 */
var buildtree = function (middleorder, preorder) {
    if (preorder.length == 0) {
        return null
    }
    //从中序遍历数组和前序遍历中得到二叉树
    //获取根节点
    let root = new TreeNode(preorder[0])
    //根据根节点去中序数组中切左右数组
    let splitnodeindex = middleorder.indexOf(root.val)
    let middleleft = middleorder.slice(0, splitnodeindex)
    let middleright = middleorder.slice(splitnodeindex + 1, middleorder.length)
    //根据中序左右数组的长度去切分左右先序数组
    //左子树的先序数组
    let preleft = preorder.slice(1, 1 + middleleft.length)
    //右子树的先序数组
    let preright = preorder.slice(1 + middleleft.length, preorder.length)
    root.left = buildtree(middleleft, preleft)
    root.right = buildtree(middleright, preright)
    return root
}
var bstFromPreorder = function (preorder) {
    //获取中序遍历数组
    let middleorder = preorder.slice(0)
    middleorder = middleorder.sort((a, b) => { return a - b })
    return buildtree(middleorder, preorder)
};