1351: 小鱼比可爱Ⅱ
题目描述
小鱼最近参加了一个“比可爱”比赛,参赛的鱼被从左到右排成一排,编号1~n,头都朝向右边,然后每只鱼会得到一个整数数值,表示这只鱼的可爱程度,很显然整数越大,表示这只鱼越可爱,而且任意两只鱼的可爱程度可能一样。由于所有的鱼头都朝向右边,所以每只鱼只能看见在它右边的鱼的可爱程度,它们心里都在计算,距自己最近且比自己可爱的小鱼是哪只呢?
输入
第一行输入一个整数 n,表示鱼的数目。n<=1000000.
第二行输入 n 个整数,用空格间隔,依次表示从左到右每只小鱼的可爱程度。 小鱼的可爱程度不超过5e4。
输出
输出一行n个整数,表示每只小鱼右边距离它最近且比它可爱的小鱼编号。若没有输出0.
样例输入
8
3 5 1 2 5 7 8 6
样例输出
2 6 4 5 6 7 0 0
思路
单调递增栈:线性时间复杂度找出每个元素右边第一个大于自身的数。
从左到右依次遍历元素,1.栈空或栈顶元素大于等于当前元素时直接入栈;2.栈顶元素小于当前元素时一直出栈直到栈空或栈顶元素大于等于当前元素。然后当前元素入栈。元素出栈时出栈元素找到了答案即当前元素,遍历结束仍未找到答案的元素无答案。
如:10,5,8,12,6。栈内状态为 {10},{10,5},{10,8}(右边第一个大于 5 的数是 8),{12}(右边第一个大于 10 和 8 的元素是 12),{12,6}(12,6 无答案)。
#include<bits/stdc++.h>
using namespace std;
const int N = 1000000 + 5;
int fish[N], ans[N];
int main()
{
int n;scanf("%d", &n);for(int i = 1; i <= n; i++)scanf("%d", &fish[i]);stack<int> s;for(int i = 1; i <= n; i++){
while(!s.empty() && fish[s.top()] < fish[i]){
ans[s.top()] = i;s.pop();}s.push(i);}for(int i = 1; i <= n; i++)printf("%d ", ans[i]);return 0;
}