IT面试题——判断合法出栈序列

在技术笔试面试上,我们常常会遇到这样一类题型,如给你一个入栈序列,然后再让你判断几个序列是否有可能为它的出栈序列,如:

入栈序列为 1 2 3 4 5,则 1 2 3 4 5可能为它的出栈序列,而 5 4 1 2 3不可能为它的出栈序列

对于n比较小的情况,我们往往可以通过手动模拟的方式来判断,对于n比较大的时候,这种方法就显得效率不佳了。

下面介绍一种通用的方法判定合法出栈序列,时间复杂度为O(n)。为了叙述方便,我们不妨设入栈序列为 1 2 3.......n,并且每个元素各不相等。

事实上,一个出栈序列固定的话,那么没个数的出栈顺序和时间都是固定的,则我们可以模拟栈的入栈出栈过程,来判断是否一个合法的出栈序列。

我们首先设po为目前为止入栈的元素中最大的数,初始化为0,若下一个出栈元素要大于po的话(设为x),说明我必须将[po+1,x]中的所有书都入栈,再将x弹出即可(这时还应把po赋值为x)。否则说明下一个出栈的元素已经在栈中,并且肯定是栈顶元素,若栈顶元素与下一个出栈元素不相等的话,我们可以判断这不是一个合法出栈序列,否则,若所有的出栈元素都不引起冲突,则说明这是一个合法序列。这里再说一下时间复杂度,因为我们只有在下一个出栈元素大于po时,才将元素压入栈中,并且我们每一次判断一个出栈元素是否发生冲突时,都会将栈顶元素弹出,所以每一个元素都入栈一次,出栈一次,所以时间复杂度为O(n)。

算法的具体实现请看代码。


代码如下:

#include <stdio.h>
#define maxn 1005
int stack[maxn],top;
int out[maxn];
int check(int n)
{
    int po=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=po+1;j<=out[i];j++)
        {
            po=j;
            stack[top++]=j;
        }
        if(stack[--top]!=out[i])
        return 0;
    }
    return 1;
}
int main()
{
    int n;
    scanf("%d",&n);//假设入栈序列为1 2。。。。n
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&out[i]);
    }
    if(check(n))
    printf("Yes\n");
    else
    printf("No\n");
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值