携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情
大家好 我是短袖撸码蒂尔尼。今天带来的是一道在LeetCode上的题目,题目难度为中等。就在此为大家分享一下解答思路。
题目阐述
给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:
创建一个根节点,其值为 nums 中的最大值。 递归地在最大值 左边 的 子数组前缀上 构建左子树。 递归地在最大值 右边 的 子数组后缀上 构建右子树。 返回 nums 构建的 最大二叉树 。
链接:原题
思路阐述
既然是二叉树 那肯定还是离不开递归
这道题目的思路不难 :
- 找出最大值作为根节点
- 以最大值为分界 建立左右节点
- 临界情况的处理
而问题就在于:怎么才能使用最小的时间复杂度来完成数组的遍历 找出最大值与对应的下标?
我本来想使用reduce方法的,当后面发现reduce没有办法做到即返回max又能返回maxIndex,因此我决定大道至简,返璞归真,用最简单的for循环 直接解决问题。
function constructMaximumBinaryTree(nums: number[]): TreeNode | null {
if (nums.length == 0)
return null
if(nums.length==1)
return new TreeNode(nums[0])
let max=nums[0]
let maxIndex=0
for (let i=1;i<nums.length;i++){
if(nums[i]>max){
max=nums[i]
maxIndex=i
}
}
let root=new TreeNode(max)
root.left=constructMaximumBinaryTree(nums.slice(0,maxIndex))
root.right=constructMaximumBinaryTree(nums.slice(maxIndex+1,nums.length))
return root
};
临界值的说明
当nums.length==0的时候,说明传入了空数组,这时候返回null
当nums.length==1的时候,说明只传入了一个值,这时候返回new TreeNode(nums[0])
题解评估
执行用时:88 ms, 在所有 TypeScript 提交中击败了91.09%的用户
内存消耗:48.5 MB, 在所有 TypeScript 提交中击败了75.25%的用户
通过测试用例:107 / 107
其他解法
那么除了递归之外,还有什么解法呢?
这里有一个单调栈的思路分享给大家:
var constructMaximumBinaryTree = function(nums) {
const n = nums.length;
const stack = [];
const tree = new Array(n).fill(0);
for (let i = 0; i < n; ++i) {
tree[i] = new TreeNode(nums[i]);
while (stack.length && nums[i] > nums[stack[stack.length - 1]]) {
tree[i].left = tree[stack[stack.length - 1]];
stack.pop();
}
if (stack.length) {
tree[stack[stack.length - 1]].right = tree[i];
}
stack.push(i);
}
return tree[stack[0]];
};
我是短袖撸码蒂尔尼
一名热爱阿森纳的前端工程师
如果本文对您有帮助,可以给一个免费的赞吗?谢谢!