本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一、题目描述:
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 中的值 互不相同
二、思路分析:
- 通过中序数组和前序数组可以确定一棵二叉树
- 二叉搜索树的中序遍历数组是一个递增数组
- 前序遍历的第一个值是根节点,通过根节点可以在中序遍历中拆分出左子树和右子树
- 根据拆分出来的左子树长度和右子树长度,可以确定前序遍历中那些节点属于左子树,哪些属于右子树
- 有了对应的左子树右子树的中序遍历数组和前序遍历数组,可以递归得到整个二叉树
- 当参数中的数组大小为空的时候,返回 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)
};