给定一个长度为 N
的整数数列,输出每个数左边第一个比它小的数,如果不存在则输出 -1
。
输入格式
第一行包含整数 N
,表示数列长度。
第二行包含 N
个整数,表示整数数列。
输出格式
共一行,包含 N
个整数,其中第 i
个数表示第 i
个数的左边第一个比它小的数,如果不存在则输出 -1
。
数据范围
1 < N < 10^5
1 < 数列中元素 < 10^9
输入样例:
输出样例:
算法思想
给定一个序列,求每一个数的左边离它最近的小于等于
或大于等于
它的数是什么。
单调栈需要维护一个单调的栈
。
注意:插入元素时需要与栈顶元素比较,以单调增为例子
。
更小则取而代之全部
,否则,正常入栈
。
筛选操作
:先保证栈顶元素就是新插入元素离得最近且最小的元素输出操作
:输出离x最近且最小的元素,如果没有就输出-1入栈操作
:x入栈,栈从数组下标1开始使用
代码实现1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| #include <iostream>
using namespace std;
const int N = 1000010;
int main(){ int n; cin >> n; int stk[N], tt = 0; while(n --){ int x; cin >> x; while(tt && x <= stk[tt]) tt--; if(tt) cout << stk[tt] << " "; else cout << "-1" << " "; stk[++tt] = x; } return 0; }
|
代码实现2(单调队列)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| #include <iostream>
using namespace std;
const int N = 100010;
int a[N], q[N], hh = 0, tt = -1;
int main(){ int n; cin >> n; for(int i = 0; i < n; i++) cin >> a[i]; for(int i = 0; i < n; i++){ while(hh <= tt && a[i] <= a[q[tt]]) --tt; if(hh <= tt) cout << a[q[tt]] << " "; else cout << "-1 "; q[++tt] = i; } return 0; }
|