数据结构与算法之二叉树: LeetCode 654. 最大二叉树 (Ts版)

最大二叉树

描述

  • 给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:
    • 创建一个根节点,其值为 nums 中的最大值
    • 递归地在最大值 左边 的 子数组前缀上 构建左子树
    • 递归地在最大值 右边 的 子数组后缀上 构建右子树
    • 返回 nums 构建的 最大二叉树

示例 1

复制代码
输入:nums = [3,2,1,6,0,5]
输出:[6,3,5,null,2,0,null,null,1]

解释:递归调用如下所示:

  • 3,2,1,6,0,5\] 中的最大值是 6 ,左边部分是 \[3,2,1\] ,右边部分是 \[0,5\] 。 * \[3,2,1\] 中的最大值是 3 ,左边部分是 \[\] ,右边部分是 \[2,1\] 。 * 空数组,无子节点。 * \[2,1\] 中的最大值是 2 ,左边部分是 \[\] ,右边部分是 \[1\] 。 * 空数组,无子节点。 * 只有一个元素,所以子节点是一个值为 1 的节点。 * \[0,5\] 中的最大值是 5 ,左边部分是 \[0\] ,右边部分是 \[\] 。 * 只有一个元素,所以子节点是一个值为 0 的节点。 * 空数组,无子节点。

复制代码
输入:nums = [3,2,1]
输出:[3,null,2,null,1]

提示

  • 1 <= nums.length <= 1000
  • 0 <= nums[i] <= 1000
  • nums 中的所有整数 互不相同

Typescript 版算法实现

1 ) 方案1:递归

ts 复制代码
/**
 * Definition for a binary tree node.
 * class TreeNode {
 *     val: number
 *     left: TreeNode | null
 *     right: TreeNode | null
 *     constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.left = (left===undefined ? null : left)
 *         this.right = (right===undefined ? null : right)
 *     }
 * }
 */

function constructMaximumBinaryTree(nums: number[]): TreeNode | null {
    const construct = (nums, left, right) => {
        if (left > right) return null;
        let best = left;
        for (let i = left + 1; i <= right; ++i) {
            if (nums[i] > nums[best]) {
                best = i;
            }
        }
        const node = new TreeNode(nums[best]);
        node.left = construct(nums, left, best - 1);
        node.right = construct(nums, best + 1, right);
        return node;
    }
    return construct(nums, 0, nums.length - 1);
};

2 ) 方案2:单调栈

ts 复制代码
/**
 * Definition for a binary tree node.
 * class TreeNode {
 *     val: number
 *     left: TreeNode | null
 *     right: TreeNode | null
 *     constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.left = (left===undefined ? null : left)
 *         this.right = (right===undefined ? null : right)
 *     }
 * }
 */

function constructMaximumBinaryTree(nums: number[]): TreeNode | null {
    const n = nums.length;
    const stack = [];
    const left = new Array(n).fill(-1);
    const right = new Array(n).fill(-1);
    const tree = new Array(n).fill(-1);
    for (let i = 0; i < n; ++i) {
        tree[i] = new TreeNode(nums[i]);
        while (stack.length && nums[i] > nums[stack[stack.length - 1]]) {
            right[stack.pop()] = i;
        }
        if (stack.length) {
            left[i] = stack[stack.length - 1];
        }
        stack.push(i);
    }

    let root = null;
    for (let i = 0; i < n; ++i) {
        if (left[i] === -1 && right[i] === -1) {
            root = tree[i];
        } else if (right[i] === -1 || (left[i] !== -1 && nums[left[i]] < nums[right[i]])) {
            tree[left[i]].right = tree[i];
        } else {
            tree[right[i]].left = tree[i];
        }
    }
    return root;
};

3 ) 方案3:单调栈优化

ts 复制代码
/**
 * Definition for a binary tree node.
 * class TreeNode {
 *     val: number
 *     left: TreeNode | null
 *     right: TreeNode | null
 *     constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.left = (left===undefined ? null : left)
 *         this.right = (right===undefined ? null : right)
 *     }
 * }
 */

function constructMaximumBinaryTree(nums: number[]): TreeNode | null {
    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]];
};
相关推荐
smj2302_796826521 分钟前
解决leetcode第3911题.移除子数组元素后第k小偶数
数据结构·python·算法·leetcode
Beginner x_u1 小时前
链表专题:JS 实现原理与高频算法题总结
javascript·算法·链表
_深海凉_4 小时前
LeetCode热题100-寻找两个正序数组的中位数
算法·leetcode·职场和发展
踩坑记录5 小时前
leetcode hot100 寻找两个正序数组的中位数 hard 二分查找 双指针
leetcode
旖-旎5 小时前
深搜练习(电话号码字母组合)(3)
c++·算法·力扣·深度优先遍历
谭欣辰5 小时前
C++快速幂完整实战讲解
算法·决策树·机器学习
Mr_pyx5 小时前
【LeetHOT100】随机链表的复制——Java多解法详解
算法·深度优先
AIFarmer5 小时前
【无标题】
开发语言·c++·算法
AGV算法笔记5 小时前
CVPR 2025 最新感知算法解读:GaussianLSS 如何用 Gaussian Splatting 重构 BEV 表示?
算法·重构·自动驾驶·3d视觉·感知算法·多视角视觉
勤劳的进取家6 小时前
数据链路层基础
网络·学习·算法