刷题——栈和排序

链接 :https://ac.nowcoder.com/acm/contest/22669/A
来源:牛客网

题目描述 
给你一个1->n的排列和一个栈,入栈顺序给定
你要在不打乱入栈顺序的情况下,对数组进行从大到小排序
当无法完全排序时,请输出字典序最大的出栈序列
输入描述:
第一行一个数n
第二行n个数,表示入栈的顺序,用空格隔开,结尾无空格
输出描述:
输出一行n个数表示答案,用空格隔开,结尾无空格
示例1
输入
5
2 1 5 3 4
输出
5 4 3 1 2
说明
2入栈;1入栈;5入栈;5出栈;3入栈;4入栈;4出栈;3出栈;1出栈;2出栈

思路: 因为要在不打乱入栈顺序的情况下,尽可能的从大到小排列。在首次操作时,只有取到这组数中的最大值,才能保证字典序最大,在最大值之前的数都放入了栈,接下来,再找最大数后的数中的最大值,因为还要考虑栈顶的元素与之后的最大值比较,栈顶大则输出栈顶,一直大就一直输出,直到栈空或者不满足栈顶大于后面未排数的最大值。最后再将栈中元素依次输出。

我的代码:

#include<bits/stdc++.h>
using namespace std;
stack<int> q;
int main()
{
    int n;
    cin>>n;
    int num[n];
    for(int i=0;i<n;i++)
        cin>>num[i];
    int m=-1;
    int k=0;
    while(k<n)
    {m=-1;
     int j=k,l=k;
        for(j;j<n;j++)//找到剩余数字中的最大值
        {
            m=max(m,num[j]);
        }
         for(l;l<n;l++)//找最大值的下标
         {
             if(num[l]==m)
             {    if(q.size()>0)//如果最大值小于栈顶元素,且栈不为空
                {
                   while(q.top()>m)//直到最大值大于栈顶元素
                  {  
                   cout<<q.top()<<" ",q.pop();//输出栈顶元素
                     if(!q.size()) break;
                  }
                }
             cout<<m<<" ";//确保栈顶比最大数小后,且后面的数都比最大值小,输出最大值
              break;
             }
         }
     for(int i=k;i<l;i++)
         q.push(num[i]);
     k=l+1;
    }
    while(q.size())//依次输出栈中元素
        cout<<q.top()<<" ",q.pop();
    
}

别人代码:

#include<stack>
#include<iostream>
using namespace std;
const int N=1e7+9;
int a[N],b[N];
stack<int> q;
int main()
{
	int n;
	cin>>n;
	//a[i]存入数组 
	for(int i=0;i<n;i++){
		cin>>a[i];
	}
	//b[i] 第i到n-1位最大的数 
	for(int i=n-1;i>=0;i--) b[i]=max(a[i],b[i+1]);
	//for(int i=0;i<n;i++) cout<<b[i];
	//输出可以排序的数 
	for(int i=0;i<n;i++){
		q.push(a[i]);
		while(!q.empty()&&q.top()>b[i+1])
		{
			cout<<q.top()<<" ";
			q.pop();
		}
	}
}

不得不说这样的写法比我的简洁多了,他是先从末开始找到每个区间的最大值,再依次放入栈中,并判断栈顶是否比当前区间的最大值大,大就输出,小就不管,最后再输出栈。简直斯巴拉西。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值