P5788 【模板】单调栈

解题思路

这道题目要求我们找到数组中每个元素右边第一个比它大的元素的下标,如果不存在则返回0。这是一个经典的单调栈应用问题。

单调栈的核心思想:维护一个栈,栈中的元素保持单调递减的顺序。当我们遍历数组时,对于当前元素,我们可以快速找到它右边第一个比它大的元素。

算法步骤:

  1. 初始化一个空栈

  2. 遍历数组中的每个元素:

    • 当栈不为空且当前元素大于栈顶元素时,说明当前元素是栈顶元素右边第一个比它大的元素,记录结果并弹出栈顶

    • 将当前元素索引入栈

  3. 遍历结束后,栈中剩余元素右边没有比它大的元素,结果记为0

时间复杂度:O(n),每个元素最多入栈和出栈一次

代码注释

#include<bits/stdc++.h>
#define ll long long  // 定义长整型别名
using namespace std;
const int N = 3e6 + 10, inf = 0x3f3f3f3f;  // 定义数组大小和无穷大值

int a[N], top;  // a数组模拟栈,top表示栈顶指针
int n;          // 数组元素个数
int b[N], ans[N]; // b存储输入数组,ans存储结果

int main()
{
    cin >> n;  // 读取数组长度
    for(int i = 1; i <= n; i++) scanf("%d", &b[i]);  // 读取数组元素
    
    int last = 1;  // 这个变量在代码中未使用,可以忽略
    for(int i = 1; i <= n; i++)  // 遍历数组
    {
        // 如果栈为空或当前元素小于栈顶元素,直接入栈
        if(top == 0 || b[i] < b[a[top]]) 
            a[++top] = i;  // 将当前索引压入栈
        else
        {
            // 当前元素大于栈顶元素时,处理栈中所有小于当前元素的元素
            while(top != 0 && b[i] > b[a[top]]){
                ans[a[top]] = i;  // 记录栈顶元素的结果为当前索引
                top--;            // 弹出栈顶
            }
            a[++top] = i;  // 将当前索引压入栈
        }
    }
    
    // 输出结果,未被处理的元素默认ans[i]=0
    for(int i = 1; i <= n; i++)
        printf("%d ", ans[i]);
    
    return 0;
}

 

posted @ 2025-07-21 19:21  CRt0729  阅读(28)  评论(0)    收藏  举报