Files
python/TangDou/AcWing/Stack/830.md
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

103 lines
2.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

##[$AcWing$ $830$.单调栈](https://www.acwing.com/problem/content/832/)
### 一、题目描述
给定一个长度为 $N$ 的整数数列,输出每个数左边第一个比它小的数,如果不存在则输出 $−1$。
**输入格式**
第一行包含整数 $N$,表示数列长度。
第二行包含 $N$ 个整数,表示整数数列。
**输出格式**
共一行,包含 $N$ 个整数,其中第 $i$ 个数表示第 $i$ 个数的左边第一个比它小的数,如果不存在则输出 $−1$。
**数据范围**
$1≤N≤10^5$
$1≤数列中元素≤10^9$
**输入样例:**
```cpp {.line-numbers}
5
3 4 2 7 5
```
**输出样例:**
```cpp {.line-numbers}
-1 3 -1 2 2
```
### 二、单调栈原理
单调栈里装的是什么?
**动态维护一个栈,把后续问题的答案都维持在这个栈中,把肯定不再有用的数字从栈中干掉。**
- 动态维护,随进随维护,不需预处理
- 将$O(N^2)$的时间复杂度降为$O(N)$
- 此类 **左侧(或右侧)最近**,**比自己大的(或小的)**,用单调栈
### 三、左边第一个比我小
```cpp {.line-numbers}
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int stk[N], tt;
int main() {
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
int x;
cin >> x;
while (tt && x <= stk[tt]) tt--;
if (tt == 0)
cout << "-1 ";
else
cout << stk[tt] << " ";
stk[++tt] = x;
}
return 0;
}
```
### 四、右边第一个比我大
```cpp {.line-numbers}
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int stk[N], tt;
/**
测试用例:右边第一个比我大
6
6 10 3 7 4 12
结果:
10 12 7 12 12 -1
*/
int a[N], res[N];
int main() {
freopen("830_RightBigger.in", "r", stdin);
int n;
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = n; i; i--) {
while (tt && a[i] >= stk[tt]) tt--;
if (tt == 0)
res[i] = -1;
else
res[i] = stk[tt];
stk[++tt] = a[i];
}
for (int i = 1; i <= n; i++) cout << res[i] << " ";
return 0;
}
```