18715 出栈序列

 解题思路:出栈序列字典序最大,可以很自然想到应该让最大的n第一个进栈再出栈,然后面临两个选择(1)继续出栈顶元素(2)继续入栈元素。
为了让字典序更大,应该在两种选择中选到值更大的元素。因此算法设计时每次出栈前都要判断(1)和(2)的最大值,决定是入栈还是出栈。实现算法时可以把第一个元素n也作为一般情况处理,具体请参看代码。

#include <iostream>
using namespace std;
int a[10005],n,s[100005],top=0;/**< s为栈结构,top为栈顶指针 */
int main()
{
    int i,j=1,k,x;
    cin>>n;
    for(i=1;i<=n;i++)
        cin>>a[i];
    for(i=1;i<=n;i++)
    {/**< 算法思想:判断可以出栈的栈顶元素和尚未入栈的元素哪个更大 */
        int maxs=a[j];/**< 先找到还没入栈的元素中最大值 */
        for(k=j;k<=n;k++)
              maxs=max(maxs,a[k]);
        if(top==0||s[top-1]<maxs)/**< 空栈或栈顶元素<未入栈最大值 */
        {
            while(a[j]!=maxs) /**< 将后面的元素依次入栈 */
                s[top++]=a[j++];
            cout<<maxs<<' ';
            j++;/**< 跳过这个maxs值 */
        }
        else
            cout<<s[--top]<<' ';/**< 栈顶元素更大,出栈 */
    }
    return 0;
}

优化:上面算法复杂度O(n^2)。求取未入栈最大值实际上是求 [j,n] 区间的最大值,可以用后缀极值数组进行优化,将复杂度降为O(n)。

int i,j,n,a[100005],mx[100005]={0};
    cin>>n;
    for(i=1;i<=n;i++)
        cin>>a[i];
    for(i=n;i>=1;i--)
        mx[i]=max(a[i],mx[i+1]);

上述代码构造后缀极值数组, 区间 [i,n]的最大值即为mx[i],这样无需循环去找区间最大值。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值