英文原文
You are given an integer array nums with no duplicates. A maximum binary tree can be built recursively from nums using the following algorithm:
- Create a root node whose value is the maximum value in
nums. - Recursively build the left subtree on the subarray prefix to the left of the maximum value.
- Recursively build the right subtree on the subarray suffix to the right of the maximum value.
Return the maximum binary tree built from nums.
Example 1:
Input: nums = [3,2,1,6,0,5]
Output: [6,3,5,null,2,0,null,null,1]
Explanation: The recursive calls are as follow:
- The largest value in [3,2,1,6,0,5] is 6. Left prefix is [3,2,1] and right suffix is [0,5].
- The largest value in [3,2,1] is 3. Left prefix is [] and right suffix is [2,1].
- Empty array, so no child.
- The largest value in [2,1] is 2. Left prefix is [] and right suffix is [1].
- Empty array, so no child.
- Only one element, so child is a node with value 1.
- The largest value in [0,5] is 5. Left prefix is [0] and right suffix is [].
- Only one element, so child is a node with value 0.
- Empty array, so no child.
Example 2:
Input: nums = [3,2,1] Output: [3,null,2,null,1]
Constraints:
1 <= nums.length <= 10000 <= nums[i] <= 1000- All integers in
numsare unique.
中文题目
给定一个不含重复元素的整数数组 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 的节点。
- 空数组,无子节点。
示例 2:
输入:nums = [3,2,1] 输出:[3,null,2,null,1]
提示:
1 <= nums.length <= 10000 <= nums[i] <= 1000nums中的所有整数 互不相同
通过代码
官方题解
方法一:递归
本方法非常简单。创建方法 construct(nums, l, r),用于找出在数组 $nums$ 中从 $l$ 到 $r$ 索引(不包含第 $r$ 个位置)中最大二叉树的根节点。
算法步骤如下:
首先调用
construct(nums, 0, n),其中 $n$ 是数组 $nums$ 的长度。在索引范围 $(l:r-1)$ 内找到最大值的索引,将 $nums[max_i]$ 作为根节点。
调用
construct(nums, l, max_i)创建根节点的左孩子。递归执行此操作,创建根节点的整个左子树。类似的,调用
construct(nums, max_i + 1, r)创建根节点的右子树。方法
construct(nums, 0, n)返回最大二叉树的根节点。
[solution1-Java]public class Solution { public TreeNode constructMaximumBinaryTree(int[] nums) { return construct(nums, 0, nums.length); } public TreeNode construct(int[] nums, int l, int r) { if (l == r) return null; int max_i = max(nums, l, r); TreeNode root = new TreeNode(nums[max_i]); root.left = construct(nums, l, max_i); root.right = construct(nums, max_i + 1, r); return root; } public int max(int[] nums, int l, int r) { int max_i = l; for (int i = l; i < r; i++) { if (nums[max_i] < nums[i]) max_i = i; } return max_i; } }
复杂度分析
时间复杂度:$O(n^2)$。方法
construct一共被调用 $n$ 次。每次递归寻找根节点时,需要遍历当前索引范围内所有元素找出最大值。一般情况下,每次遍历的复杂度为 $O(\log n)$,总复杂度为 $O\big(n\log n\big)$。最坏的情况下,数组 $nums$ 有序,总的复杂度为 $O(n^2)$。空间复杂度:$O(n)$。递归调用深度为 $n$。平均情况下,长度为 $n$ 的数组递归调用深度为 $O(\log n)$。
统计信息
| 通过次数 | 提交次数 | AC比率 |
|---|---|---|
| 66996 | 82742 | 81.0% |
提交历史
| 提交时间 | 提交结果 | 执行时间 | 内存消耗 | 语言 |
|---|
相似题目
| 题目 | 难度 |
|---|---|
| 最大二叉树 II | 中等 |