最大二叉树

@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(nlogn)O(n\log n) 的。应该也可以实现一种从左到右遍历数组的方法,不过因为在往树中插入新节点之后可能需要对树的结构进行调节,以保证其满足最大二叉树的性质,所以那种遍历的方法的时间复杂度应该也不会是 O(n)O(n) 的,感觉上应该也是也会是 O(nlogn)O(n\log n) 的。因为初步感觉上两种方法差不多,所以没有对第二种思路进行详细分析,直接实现了第一种分治递归地方式。最后的提交结果证明,这种方法的效率还是可以的。

/**
 * 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% 的用户
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章