题目描述
给定一个不含重复元素的整数数组 nums 。一个以此数组直接递归构建的 最大二叉树 定义如下:
- 二叉树的根是数组 nums 中的最大元素。
- 左子树是通过数组中 最大值左边部分 递归构造出的最大二叉树。
- 右子树是通过数组中 最大值右边部分 递归构造出的最大二叉树。
返回有给定数组 nums 构建的 最大二叉树 。
示例 1:
输入:nums = [3,2,1,6,0,5]
输出:[6,3,5,null,2,0,null,null,1]
解题过程
1.解题思路
首先,依据题目,我们也能很明显的看出递归的思路。
-
二叉树的根是数组 nums 中的最大元素。
-
左子树是通过数组中 最大值左边部分 递归构造出的最大二叉树。
-
右子树是通过数组中 最大值右边部分 递归构造出的最大二叉树。
接下来,循着这个简单思路,我们很容易得出如下的伪码:
dfs(nums):
max = nums最大值;
root = new TreeNode(max);
root.left = dfs(nums左侧);
root.right = dfs(nums右侧);
return root;
2.代码实现细节
为了方便记录nums的左侧和右侧信息,我们在每次递归时应该传递与左侧右侧相关的下标信息,也就是应该传递这样一个参数列表(int[] nums, int start, int end)。另外需要注意一下数组的边界问题,然后顺着思路就能写出我们的代码了。
3.示例代码
class Solution {
public TreeNode constructMaximumBinaryTree(int[] nums) {
return build(nums, 0, nums.length - 1);
}
public TreeNode build(int[] nums, int start, int end){
int maxIndex = getMaxElementIndex(nums, start, end);
int rootVal = nums[maxIndex];
TreeNode root = new TreeNode(rootVal);
if(maxIndex - 1 >= start){
root.left = build(nums, start, maxIndex - 1);
}
if(maxIndex + 1 <= end){
root.right = build(nums, maxIndex + 1, end);
}
return root;
}
public int getMaxElementIndex(int[] nums, int start, int end){
int maxIndex = start;
for(int i=start;i<=end;i++){
if(nums[i]>nums[maxIndex]){
maxIndex = i;
}
}
return maxIndex;
}
}
时间复杂度:O(n^2)。方法 build 一共被调用 n 次。每次递归寻找根节点时,需要遍历当前索引范围内所有元素找出最大值。而查找最大元素的时间复杂度平均为O(logn),但在有序的情况下最坏为O(n)。所以时间复杂度为O(n^2)。
空间复杂度:O(n)。递归调用深度为 n。
题解原链接:最大二叉树的递归解法 - 最大二叉树 - 力扣(LeetCode)(该题解作者也为本人)