@author: sdubrz
@date: 2020.04.14
题目难度: 中等
考察内容: 树
原题链接 https://leetcode-cn.com/problems/maximum-binary-tree/
题目的著作权归领扣网络所有,商业转载请联系官方授权,非商业转载请注明出处。
解题代码转载请联系 lwyz521604#163.com
给定一个不含重复元素的整数数组。一个以此数组构建的最大二叉树定义如下:
二叉树的根是数组中的最大元素。
左子树是通过数组中最大值左边部分构造出的最大二叉树。
右子树是通过数组中最大值右边部分构造出的最大二叉树。
通过给定的数组构建最大二叉树,并且输出这个树的根节点。
示例 :
输入:[3,2,1,6,0,5]
输出:返回下面这棵树的根节点:
6
/ \
3 5
\ /
2 0
\
1
提示:
- 给定的数组的大小在 [1, 1000] 之间。
通过次数12,808提交次数15,940
解法
看到这道题,首先想到的一种简单的实现方法就是每次挑选出最大值之后,分别递归地对最大值左边和右边的部分建树。这种分治递归的方法时间复杂度应该是 O ( n log n ) O(n\log n) O(nlogn) 的。应该也可以实现一种从左到右遍历数组的方法,不过因为在往树中插入新节点之后可能需要对树的结构进行调节,以保证其满足最大二叉树的性质,所以那种遍历的方法的时间复杂度应该也不会是 O ( n ) O(n) O(n) 的,感觉上应该也是也会是 O ( n log n ) O(n\log n) O(nlogn) 的。因为初步感觉上两种方法差不多,所以没有对第二种思路进行详细分析,直接实现了第一种分治递归地方式。最后的提交结果证明,这种方法的效率还是可以的。
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public TreeNode constructMaximumBinaryTree(int[] nums) {
if(nums.length==0){
return null;
}
TreeNode root = this.mbTree(nums, 0, nums.length-1);
return root;
}
private TreeNode mbTree(int[] nums, int start, int finish) {
int max = this.maxIndex(nums, start, finish);
TreeNode root = new TreeNode(nums[max]);
if(start==finish) {
return root;
}
if(max>start) { // 左边有没有用的数组
root.left = this.mbTree(nums, start, max-1);
}
if(max<finish) { // 右边还有没有用的数组
root.right = this.mbTree(nums, max+1, finish);
}
return root;
}
private int maxIndex(int[] nums, int start, int finish) {
int max = start;
for(int i=start; i<=finish; i++) {
if(nums[max]<nums[i]) {
max = i;
}
}
return max;
}
}
在 LeetCode 系统中提交的结果如下所示
执行结果: 通过 显示详情
执行用时 : 2 ms, 在所有 Java 提交中击败了 100.00% 的用户
内存消耗 : 40 MB, 在所有 Java 提交中击败了 25.00% 的用户