LeetCode-946 验证栈序列

题记:程序猿每天都在教世界上最笨的学生——计算机。

以下面这个数据结构课程经典课后选择题——出栈序列为例,这是高校经典数据结构课本——严蔚敏老师的数据结构第2版第3章栈和队列的第一个选择题,再简单不过了,给定入栈序列,判断下列哪个选项的出栈序列是正确的。要看出这个题的正确选项并不难,可如何让计算机来判断一个序列是不是按照先进后出的原则出栈的呢?从中我们可以窥见一斑,编程是一件非常困难的事,因为你在教世界上最笨的学生——计算机。

LeetCode-946 验证栈序列_第1张图片

这是今天我在刷LeetCode周赛的时候看到的一个题目,题目描述:给定pushed和popped两个序列,只有当它们可能是在最初空栈上进行的推入push 和弹出 pop 操作序列的结果时,返回true;否则,返回false。

例如:若pushed=[1,2,3,4,5],popped=[4,5,3,2,1],则返回true。因为入栈出栈的顺序可以是这样的:1入栈,2入栈,3入栈,4入栈,4出栈,5入栈,5出栈,3出栈,2出栈,1出栈。

又例如:若pushed=[1,2,3,4,5],popped=[4,3,5,1,2],则返回false。因为1不能在2之前出栈。

殊不知我们人用“肉眼”一眼就看出了答案,计算机却没有那么聪明,需要进行机械的运算。那么不用怕,接下来要做的就是仔细研究一下“自己的大脑”,自己是如何快速看出答案的,自己的大脑经过了怎样的运算,搞清楚这些之后,便可以将自己的思想通过编程传递给计算机,从而教会了计算机这个笨学生。

经过整理思维,我发现我的大脑经历了这样一个过程:先看popped序列的第一个元素,然后比较pushed序列的第一个元素,若发现两个元素不一样,则先将pushed序列的第一个元素入栈,然后再将pushed序列的第二个元素与popped序列的第一个元素相比......直到在pushed序列中找到一个与popped序列第一个元素相同的元素,然后此时popped序列才跳到第二个元素(即下一个元素)......pushed序列经过一轮对比到了尽头(此时popped序列可能还未到尽头),若popped序列还未比较到尽头则接下来就要比较popped序列和栈内的元素了,将栈内元素一个一个出栈与popped序列中未经比较的元素相比较,若此时出现有一个不同元素,则此popped序列非出栈序列。

以上只是粗略整理了一下自己大脑的分析策略,总之最核心的是先假设popped序列就是出栈序列,直到出栈的时候发现有元素不相同的情况才认定popped序列不是出栈序列。下面需要转换成计算机容易实现的策略,做到“因材施教”。

在下面的代码中我将“相同”称之为“匹配”,代码使用纯C语言实现(C语言中没有bool类型的变量,但是在LeetCode上使用C语言提交代码的时候很多的题目都要求返回bool类型的变量),其中pushedSize为pushed序列的长度,poppedSize为popped序列的长度,由于题目规定0<=pushed.length==popped.length<=1000,所以我将栈数组开1001的大小。代码字里行间的注释可能带有一些个人特色,还望各位读者海涵。

bool validateStackSequences(int* pushed, int pushedSize, int* popped, int poppedSize)
{
    //先假定popped序列就是出栈序列
    //等出现异常情况再将其改为false也不迟
    int flag=true;
    //自定义的栈结构
    int Stack[1001];
    //栈顶
    int top=0;
    int i,j;
    //i为游走的pushed序列下标
    i=0;
    //j为游走的popped序列下标
    j=0;
    while(i0&&Stack[top-1]==popped[j])
            {
                //匹配成功则真的出栈
                --top;
                //将j后移一位
                j++;
            }
            //出栈元素还与popped[j]不匹配则将pushed[i]入栈
            else
            {
                Stack[top++]=pushed[i];
                //将i后移一位
                i++;
            }
        }
    }
    //若栈还没空则一直循环
    while(top>0)
    {
        //出现不相匹配的情况
        if(Stack[top-1]!=popped[j])
        {
            //怎么样
            //现在改过来还不迟吧
            //逃不过老子的火眼金睛
            flag=false;
            break;
        }
        //呦呵
        //还是匹配成功的
        //那我再出栈一个元素跟你比较
        else
        {
            --top;
            //将j后移一位
            j++;
        }
    }
    //最后若始终找不到异常,则flag还是true
    return flag;
}

想必各位都体验过“教计算机做人”这痛苦的过程,有很多的问题都是明明在人脑看来特别简单,在编程实现的时候会遇到种种困难甚至是坑,有时做出来也会有各种各样的bug。但是计算机这学生虽然笨,用处却很大,教会了它,它就能替人类不知疲惫地干活,做大量重复的工作,大大节省了人力资源。

欢迎大家关注/订阅我的微信公众号Code Art Online,我会在我的公众号分享个人见闻,发现生活趣味;这里不仅有0和1,还有是诗和远方↓↓↓

你可能感兴趣的:(题解)