算法学习——单调栈

单调栈

以下为acwing算法学习笔记

常见题型

从第0~i-1个数中找出比第i个数小的下标值最大的数

1.暴力做法

两层for循环
for(int i=0;i<n;i++)
  for(int j=i-1;j>=0;j--)
  {   
      if(a[j]<a[i]) cout<<a[j];
  }
  //a[j]即为最终要找的数

2.优化:单调栈

通过观察可以发现,若aj>=ak,且j<k<i, aj<ai, ak<ai,则aj永远不会被输出,因为ak不大于ai并且距离ai更近。如果利用栈来存储ai之前的数字,那么aj就没有必要压入栈中。最终栈里面存储的一定是一个单调增序列。

题目

给定一个长度为 N 的整数数列,输出每个数左边第一个比它小的数,如果不存在则输出 −1。

输入格式
第一行包含整数 N,表示数列长度。

第二行包含 N 个整数,表示整数数列。

输出格式
共一行,包含 N 个整数,其中第 i 个数表示第 i 个数的左边第一个比它小的数,如果不存在则输出 −1。

数据范围
1≤N≤105
1≤数列中元素≤109
输入样例:
5
3 4 2 7 5
输出样例:
-1 3 -1 2 2

#include<iostream>
using namespace std;

const int N=100005;
//stack 栈 t 栈顶指针
int stack[N],t;
int n;
int main()
{
  scanf("%d",&n);
  for(int i=1;i<=n;i++){
     int x;
     scanf("%d",&x);
     //如果栈非空并且栈顶元素大于等于x,则将栈顶元素删掉
     while(t&&stack[t]>=x) t--;
     //删掉之后若栈非空,则当前栈顶元素为距离x最近的比x小的数
     if(t) cout<<stack[t]<<' ';
     //否则不存在这样的数,输出-1
     else cout<<"-1"<<' ';
     stack[++t]=x;
  }
  return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值