左边第一个小的数

【问题描述】

给定一个数组,输出每个对每个位置而言左边第一个比其小的数的位置,如果不存在则输出-1。

【输入形式】

第一行一个数n<=10^5,表示数组大小。

第二行n个数,描述数组。

【输出形式】

一行n个数

【样例输入】

10

10 2 4 5 3 1 2 8 9 6

【样例输出】
-1 -1 2 3 2 -1 6 7 8 7
思路:
1.使用单调栈,用一个类保存元素的位置和数据。
当前数入栈时,所有比当前数大的元素出栈。
每次输出栈顶元素的位置后,自己进栈。
2.递归,对每个元素,找左边的邻居的比他小的元素的位置,看那个元素是不是比自己小,不断往前跳直到找到或者跳到第一个。

解决代码

方法一

#include <iostream>
#include <stack>
using namespace std;
class node{
public:
    int data;
    int num;
    node(int data1,int num1):data(data1),num(num1){};
};
int main() {
    stack<node>s;
    int n=0;int input=0;int i=0;
    cin>>n;
    for (i=1; i<=n; i++) {
        cin>>input;
        node* n=new node(input,i);
        while (!s.empty()&&input<s.top().data) {
            s.pop();
        }
        if (s.empty()) {
            cout<<-1<<' ';
        }
        else{
            cout<<s.top().num<<' ';
        }
        s.push(*n);
    }
    return 0;
}

方法二

#include <iostream>
using namespace std;
int main() {
int i=0;int j=0;
     int len=0;
    cin>>len;
    int *p=new int[len];
    int *b=new int[len];
    if(len==0)return 0;
    for(i=0;i!=len;i++)
    {cin>>p[i];
      }
    b[0]=-1;
    for (i=1; i<len; i++) {
        j=i-1;
        while (p[i]<=p[j]) {
            j=b[j];
            if(j==-1){
                break;}
        }
        b[i]=j;
    }
    for (i=0; i<len-1; i++) {
        if(b[i]==-1)cout<<-1<<' ';
            else cout<<b[i]+1<<' ';
    }
    if(b[len-1]==-1)cout<<-1;
    else cout<<b[len-1]+1;
    return 0;
}


反思:有序栈的使用使得思路简便很多。它可以保存以当前元素为上/下界的所有元素。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值