数据结构_栈和单调栈
Posted hot-machine
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构_栈和单调栈相关的知识,希望对你有一定的参考价值。
数组模拟栈
代码模板
const int N = 1e6 + 10;
int st[N], tt = -1;
void push(int x) {
st[++tt] = x;
}
void pop() {
--tt;
}
bool isempty() {
return tt >= 0;
}
void query() {
cout << st[tt] << endl;
}
单调栈
- 题目描述1: 给定一个长度为N的整数数列,输出每个数++左边++++第一个比它小的数++,如果不存在则输出-1。
暴力做法(TLE):双指针算法
void solve() {
for(int i = 0; i < n; i++) {
int j = i - 1;
while(j != -1 && st[j] > a[i]) j--;
if(j) printf("%d ", st[j]);
else printf("-1 ");
}
}
单调栈
思路分析:
- 假设i < j, 而且a[i] > a[j], 如果a[i]满足条件,则a[j]也必然满足条件。
- 题目要求输出每个数左边第一个比它小的数,因此输出a[j], 而a[i]一定不会用到。
- 由此可以得出一个规律:在这个题中,只要存在以下这种情况:
i < j
a[i] > a[j]
- 即下标小,而其数值反而大的情况一定不会采用。
- 因此我们完全可以不考虑这种数,而把有用的数单独存储起来,可以选择栈这种数据结构
- 而最终我们得到的栈中的元素都满足这样的规律:单调性
i < j
a[i] < a[j]
代码模板
const int N = 1e6 + 10;
int st[N], tt = 0;
void solve() {
for(int i = 0; i < n; i++) {
while(tt && st[tt] >= a[i]) tt--;
if(tt) printf("%d ", st[tt]);
else printf("-1 ");
st[++tt] = a[i];
}
}
- 题目描述2:数列中第 i 个元素之后第一个大于a[i]的元素的下标
const int N = 3e6 + 10; // 根据题目数据范围
int st[N], a[N], ans[N], tt = 0; // 数组模拟的栈从下标为1开始存储
void solve() {
int n; scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
for(int i = n; i >= 1; i--) {
while(tt && a[st[tt]] <= a[i]) tt -- ; // 删去比当前位置的数小的,剩下第一个比当前的数大的
ans[i] = (tt) ? st[tt]: 0;
st[++tt] = i;
}
for(int i = 0; i < n; i++) printf("%d ", ans[i]);
}
以上是关于数据结构_栈和单调栈的主要内容,如果未能解决你的问题,请参考以下文章