题目描述
对于一个没有重复元素的整数数组,请用其中元素构造一棵MaxTree,MaxTree定义为一棵二叉树,其中的节点与数组元素一一对应,同时对于MaxTree的每棵子树,它的根的元素值为子树的最大值。现有一建树方法,对于数组中的每个元素,其在树中的父亲为数组中它左边比它大的第一个数和右边比它大的第一个数中更小的一个。若两边都不存在比它大的数,那么它就是树根。请证明这个方法的正确性,同时设计O(n)的算法实现这个方法。
给定一个无重复元素的数组A和它的大小n,请返回一个数组,其中每个元素为原数组中对应位置元素在树中的父亲节点的编号,若为根则值为-1。
测试样例:
[3,1,4,2],4
返回:[2,0,-1,2]
import java.util.*;
public class MaxTree {
public int[] buildMaxTree(int[] A, int n) {
int result[]=new int[A.length];
Arrays.fill(result, -1);
Stack<node> stack=new Stack<>();
int leftIndex[]=new int[A.length];
Arrays.fill(leftIndex, -1);
for(int i=0;i<A.length;i++)
{
while(stack.size()>0&&stack.peek().val<A[i])
{
stack.pop();
}
if(stack.size()>0)
{
leftIndex[i]=stack.peek().index;
}
stack.push(new node(A[i], i));
}
stack=new Stack<>();
int rightIndex[]=new int[A.length];
Arrays.fill(rightIndex, -1);
for(int i=A.length-1;i>=0;i--)
{
while(stack.size()>0&&stack.peek().val<A[i])
{
stack.pop();
}
if(stack.size()>0)
{
rightIndex[i]=stack.peek().index;
}
stack.push(new node(A[i], i));
}
for(int i=0;i<A.length;i++)
{
int left=Integer.MAX_VALUE;
if(leftIndex[i]!=-1)
{
left=A[leftIndex[i]];
}
int right=Integer.MAX_VALUE;
if(rightIndex[i]!=-1)
{
right=A[rightIndex[i]];
}
if(left!=Integer.MAX_VALUE||right!=Integer.MAX_VALUE)
{
result[i]=left<right?leftIndex[i]:rightIndex[i];
}
}
return result;
}
class node{
public int val;
public int index;
public node(int val,int index)
{
this.val=val;
this.index=index;
}
}
}
参看文献
http://blog.csdn.net/brandohero/article/details/41858463