【每日一题记录】654. 最大二叉树

104 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 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])

题解评估

image.png

执行用时:88 ms, 在所有 TypeScript 提交中击败了91.09%的用户

内存消耗:48.5 MB, 在所有 TypeScript 提交中击败了75.25%的用户

通过测试用例:107 / 107

其他解法

那么除了递归之外,还有什么解法呢?
这里有一个单调栈的思路分享给大家:

image.png

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]];
};

我是短袖撸码蒂尔尼
一名热爱阿森纳的前端工程师
如果本文对您有帮助,可以给一个免费的赞吗?谢谢!

名片.jpg