![Go程序员面试算法宝典](https://wfqqreader-1252317822.image.myqcloud.com/cover/262/26268262/b_26268262.jpg)
2.4 如何根据入栈序列判断可能的出栈序列
难度系数:★★★☆☆
被考查系数:★★★★★
题目描述:
输入两个整数序列,其中一个序列表示栈的push(入)顺序,判断另一个序列有没有可能是对应的pop(出)顺序。
分析与解答:
假如输入的push序列是1、2、3、4、5,那么3、2、5、4、1 就有可能是一个pop序列,但5、3、4、1、2 就不可能是它的一个pop序列。
主要思路是使用一个栈来模拟入栈顺序,具体步骤如下:
(1)把push序列依次入栈,直到栈顶元素等于pop序列的第一个元素,然后栈顶元素出栈,pop序列移动到第二个元素。
(2)如果栈顶继续等于pop序列现在的元素,则继续出栈并pop后移;否则对push序列继续入栈。
(3)如果push序列已经全部入栈,但是pop序列未全部遍历,而且栈顶元素不等于当前pop元素,那么这个序列不是一个可能的出栈序列。如果栈为空,而且pop序列也全部被遍历过,则说明这是一个可能的pop序列。下图给出一个合理的pop序列的判断过程。
![](https://epubservercos.yuewen.com/C814A1/14700476404565706/epubprivate/OEBPS/Images/83_01.jpg?sign=1738948345-oSbqDB7hEti1ZY5WoA29YtcQiRZAI0JP-0-11147f5e044fa08966babe0fec704487)
在上图中,(1)~(3)三步,由于栈顶元素不等于pop序列第一个元素3,因此,1,2,3依次入栈,当3入栈后,栈顶元素等于pop序列的第一个元素3,因此,第(4)步执行3出栈,接下来指向第二个pop序列2,且栈顶元素等于pop序列的当前元素,因此,第(5)步执行2出栈;接着由于栈顶元素4不等于当前pop序列5,因此,接下来(6)和(7)两步分别执行4和5入栈;接着由于栈顶元素5等于pop序列的当前值,因此,第(8)步执行5出栈,接下来(9)和(10)两步栈顶元素都等于当前pop序列的元素,因此,都执行出栈操作。最后由于栈为空,同时pop序列都完成了遍历,因此,{3,2,5,4,1}是一个合理的出栈序列。
实现代码如下:
![](https://epubservercos.yuewen.com/C814A1/14700476404565706/epubprivate/OEBPS/Images/83_02.jpg?sign=1738948345-FTR0YOhvXHkcaiAxMFrwS6n9yMgByPz3-0-b1f067d42086e42b63c178f38339f071)
![](https://epubservercos.yuewen.com/C814A1/14700476404565706/epubprivate/OEBPS/Images/84_01.jpg?sign=1738948345-ZfuNHr9yqufQMon6tKs2pqqISGOvjBz3-0-f238cf9b9c213d27caa01f7fd08bdff3)
程序的运行结果为
![](https://epubservercos.yuewen.com/C814A1/14700476404565706/epubprivate/OEBPS/Images/84_02.jpg?sign=1738948345-LS6jdQZlC8vw4jMHLYRPioc6GMBrkDxw-0-141cab7d2fe8c2f7e76503144f2f81ef)
算法性能分析:
这种方法在处理一个合理的pop序列的时候需要操作的次数最多,即把push序列进行一次压栈和出栈操作,操作次数为2n,因此,时间复杂度为O(n),此外,这种方法使用了额外的栈空间,因此,空间复杂度为O(n)。