对于一个没有重复元素的整数数组,请用其中元素构造一棵MaxTree,MaxTree定义为一棵二叉树,其中的节点与数组元素一一对应,同时对于MaxTree的每棵子树,它的根的元素值为子树的最大值。现有一建树方法,对于数组中的每个元素,其在树中的父亲为数组中它左边比它大的第一个数和右边比它大的第一个数中更小的一个。若两边都不存在比它大的数,那么它就是树根。请设计O(n)的算法实现这个方法。
给定一个无重复元素的数组A和它的大小n,请返回一个数组,其中每个元素为原数组中对应位置元素在树中的父亲节点的编号,若为根则值为-1。
测试样例:
输入:[3,1,4,2],4
返回:[2,0,-1,2]
class MaxTree {
public:
vector<int> buildMaxTree(vector<int> A, int n) {
// write code here
// 利用stack存储局部最值
stack<int> stk_l;
vector<int> left(n);
vector<int> right(n);
// 找左边
for(int i=0; i<n; i++){
while(!stk_l.empty() && A[i] > A[stk_l.top()]){
stk_l.pop();
}
if(stk_l.empty()){
left[i] = -1;
}else{
left[i] = stk_l.top();
}
stk_l.push(i);
}
// 找右边
stack<int> stk_r;
for(int i=n-1; i>=0; i--){
while(!stk_r.empty() && A[i] > A[stk_r.top()]){
stk_r.pop();
}
if(stk_r.empty()){
right[i] = -1;
}else{
right[i] = stk_r.top();
}
stk_r.push(i);
}
// 合并
vector<int> result(n);
for(int i=0; i<n; i++){
if(-1 == left[i]){
if(-1 == right[i]){
result[i] = -1;
}else{
result[i] = right[i];
}
}else{
if(-1 == right[i]){
result[i] = left[i];
}else{
result[i] = A[left[i]] < A[right[i]] ? left[i] : right[i];
}
}
}
return result;
}
};