数据结构_栈和单调栈

数组模拟栈

代码模板

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]);
}

原文链接: https://www.cnblogs.com/Hot-machine/p/13191638.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    数据结构_栈和单调栈

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/358827

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 下午12:29
下一篇 2023年3月2日 下午12:29

相关推荐