T : 仰视奶牛
Time Limit:1 Sec Memory Limit:128 MiB
Back Submit Edit
Description
约翰有N头奶牛,编号为1到N。
现在这N头奶牛按编号从小到大的顺序站成了一排,其中奶牛 i 的身高为Hi。
现在,每头奶牛都向它的右侧望向那些编号较大的奶牛,对于奶牛 i 如果存在一头奶牛 j 满足 i < j 并且 Hi < Hj,那么我们称奶牛 i 需要仰视奶牛 j。
请你求出每头奶牛的最近仰视对象。
Input
第一行包含整数N。
接下来N行,每行包含一个整数Hi,其中第 i 行的数为编号为 i 的奶牛的高度。
数据范围
1 ≤ N ≤ 10^5
1 ≤ Hi ≤ 10^6
Output
共 N 行,每行输出一个整数,其中第 i 行的输出整数表示编号为 i 的奶牛的最近仰视对象的编号,如果不存在仰视对象,则输出0。
Sample Input
6
3
2
6
1
1
2
Sample Output
3
3
0
6
6
0
More Info
#include<iostream>
#include<stack>
#include<unordered_map>
using namespace std;
const int maxn=100010;
int f[maxn],sum[maxn];//sum数组存储最终结果
int main() {
// freopen("qwe.txt","r",stdin);
int n;
unordered_map<int ,int >ma;//散列映射值和位置,因为在单调栈中是不会有重复数出现的所以可以放心使用
stack<int>sta;
cin>>n;
for(int i=1; i<=n; i++)
scanf("%d",&f[i]);
sum[n]=0;
sta.push(f[n]);
ma[f[n]]=n;//初始化栈和位置映射
for(int i=n-1; i>=1; i--) {
//单调递增栈从后往前遍历
if(sta.empty()) {
//当栈中为空时
//将该数据入栈、建立位置映射、答案数组为0
sta.push(f[i]);
ma[f[i]]=i;
sum[i]=0;
continue;
}
else if(f[i]<sta.top()) {
sum[i]=ma[sta.top()];
sta.push(f[i]);
ma[f[i]]=i;
//当前数据小于栈顶元素时符合栈单调递增
// 注意顺序先记录答案数组、然后将该数据入栈、建立映射
continue;
} else {
while(!sta.empty()&&f[i]>=sta.top()) {
//当前数据与栈顶元素不符合递增序列时就依次将栈顶元素出栈
//还要擦去相应的位置映射
ma.erase(sta.top());
sta.pop();
}
if(sta.empty()) {
//当最终符合单调递增的规则时
//若栈为空说明要赋值答案数组为0然后入栈建立相应的位置映射
sum[i]=0;
sta.push(f[i]);
ma[f[i]]=i;
} else {
//当栈不为空时记录答案数组入栈建立相应的位置映射
sum[i]=ma[sta.top()];
sta.push(f[i]);
ma[f[i]]=i;
}
}
}
for(int i=1; i<=n; i++)
printf("%d\n",sum[i]);
return 0;
}