Given an integer array with no duplicates. A max tree building on this array is defined as follow:
- The root is the maximum number in the array
- The left subtree and right subtree are the max trees of the subarray divided by the root number.
Construct the max tree by the given array.
Example
Example 1:
Input:[2, 5, 6, 0, 3, 1]
Output:{6,5,3,2,#,0,1}
Explanation:
the max tree constructed by this array is:
6
/ \
5 3
/ / \
2 0 1
Example 2:
Input:[6,4,20]
Output:{20,6,#,#,4}
Explanation:
20
/
6
\
4
Challenge
O(n) time and memory.
思路:暴力解:用dfs;会time out;
/**
* Definition of TreeNode:
* public class TreeNode {
* public int val;
* public TreeNode left, right;
* public TreeNode(int val) {
* this.val = val;
* this.left = this.right = null;
* }
* }
*/
public class Solution {
/**
* @param A: Given an integer array with no duplicates.
* @return: The root of max tree.
*/
public TreeNode maxTree(int[] A) {
if(A == null || A.length == 0 ) return null;
return buildMaxTree(A, 0, A.length-1);
}
private TreeNode buildMaxTree(int[] A, int start, int end) {
if(start > end) {
return null;
}
if(start == end) {
return new TreeNode(A[start]);
}
// find max;
int index = start;
for(int i = start; i<= end; i++) {
if(A[i] >= A[index]){
index = i;
}
}
TreeNode root = new TreeNode(A[index]);
root.left = buildMaxTree(A, start, index-1);
root.right = buildMaxTree(A, index+1, end);
return root;
}
}
最优解:用单调递减栈,因为L, <x, <x....X, <x, <x, R, (L>X, R>X) X能够给他父亲的,只能是L , R中的一个. 所以,这题变成了找左右两边第一个比X大的点,用单调递减栈;
取最小值,然后分别接到左右(看X是连接在L,R的左边还是右边);
/**
* Definition of TreeNode:
* public class TreeNode {
* public int val;
* public TreeNode left, right;
* public TreeNode(int val) {
* this.val = val;
* this.left = this.right = null;
* }
* }
*/
public class Solution {
/**
* @param A: Given an integer array with no duplicates.
* @return: The root of max tree.
*/
public TreeNode maxTree(int[] A) {
if(A == null || A.length == 0) {
return null;
}
Stack<TreeNode> stack = new Stack<TreeNode>();
for(int i = 0; i <= A.length; i++) {
TreeNode node = (i == A.length) ? new TreeNode(Integer.MAX_VALUE)
: new TreeNode(A[i]);
while(!stack.isEmpty() && stack.peek().val <= node.val){
TreeNode curnode = stack.pop();
//核心就是安排pop出来的点,是去L,还是R的左边还是右边;
// 注意因为上面pop了,这里一定要判断一下stack是否为空;
if(!stack.isEmpty() && node.val > stack.peek().val) {
stack.peek().right = curnode;
} else {
// node.val <= stack.peek().val;
node.left = curnode;
}
}
stack.push(node);
}
return stack.pop().left;
}
}