双栈排序(栈+二分图)

牛客题面:双栈排序

题面大意:

给定一个整数 n n n 和一个初始序列 a a a,其中序列 a a a 的值为[1,n]不重复的正整数。
现在有以下四个操作,希望能够凭借这四个操作使得序列 a a a 成为一个升序的序列。

  1. 操作a:如果输入序列不为空,将第一个元素压入栈S1
  2. 操作b:如果栈S1不为空,将S1栈顶元素弹出至输出序列
  3. 操作c:如果输入序列不为空,将第一个元素压入栈S2
  4. 操作d:如果栈S2不为空,将S2栈顶元素弹出至输出序列

让我们判断,初始序列 a a a 是否能够通过以上四个操作得到升序序列,如果不能输出 0 0 0 ;如果可以输出字典序最小的操作序列。

思路:

当我们只考虑一个栈的时候,很显然有一个固定的操作:
在序列 a a a 中从前往后遍历每个数,先将当前数压入栈中,如果之后的所有数值都比栈顶数值来得大,则需要将栈顶弹出,否则不弹出。

所以,当我们拓展到两个栈的时候,我们只要考虑当前数要压入第一个栈还是第二个栈就行了,其余操作与上述一致。

这里有一个很强的性质:
当两数 a [ i ] < a [ j ] , ( i < j ) a[i] < a[j],(i<j) a[i]<a[j],(i<j) 时,这两个数不存在于同一个栈中,当且仅当,存在 k > j k > j k>j 时,有 a [ k ] < a [ i ] < a [ j ] a[k]<a[i]<a[j] a[k]<a[i]<a[j]

证明如下:

充分性:
a [ i ] a[i] a[i]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值