其他分享
首页 > 其他分享> > 剑指offer(第二版)——栈的压入弹出序列

剑指offer(第二版)——栈的压入弹出序列

作者:互联网

PS:《剑指offer》是很多同学找工作都会参考的一本面试指南,同时也是一本算法指南(为什么它这么受欢迎,主要应该是其提供了一个循序渐进的优化解法,这点我觉得十分友好)。现在很多互联网的算法面试题基本上可以在这里找到影子,为了以后方便参考与回顾,现将书中例题用Java实现(第二版),欢迎各位同学一起交流进步。

GitHub: https://github.com/Uplpw/SwordOffer

完整题目链接: https://blog.csdn.net/qq_41866626/article/details/120415258

目录

1 题目描述

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如,序列 {1,2,3,4,5} 是某栈的压栈序列,序列 {4,5,3,2,1} 是该压栈序列对应的一个弹出序列,但 {4,3,5,1,2} 就不可能是该压栈序列的弹出序列。

示例 1:

输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
输出:true
解释:我们可以按以下顺序执行:
push(1), push(2), push(3), push(4), pop() -> 4,
push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1

leetcode链接: 栈的压入弹出序列(以下代码已测试,提交通过)

2 测试用例

一般是考虑功能用例,特殊(边缘)用例或者是反例,无效测试用例这三种情况。甚至可以从测试用例寻找一些规律解决问题,同时也可以让我们的程序更加完整鲁棒。

(1)功能用例:正常的进栈、出栈序列,包括是和不是其序列。

(2)边缘用例:连续压栈,出栈。

(3)无效用例:栈空。

3 思路

分析:

该题考查栈的性质:后进先出。因此我们利用模拟进栈出栈的过程即可。

对于一个给定的压入序列,由于弹出的时机不同,会出现多种弹出序列。依照后进先出的原则,复现一下栈的压入弹出过程就很容易判断了。主要步骤如下:

步骤1:栈压入序列第一个元素,弹出序列指针指弹出序列的第一个;
步骤2:判断栈顶元素是否等于弹出序列的第一个元素:
    步骤2.1:如果不是,压入另一个元素,进行结束判断,未结束则继续执行步骤2;
    步骤2.2:如果是,栈弹出一个元素,弹出序列指针向后移动一位,进行结束判断(pop数组是否索引完),未结束则继续执行步骤2;

结束条件:如果弹出序列指针还没到结尾但已经无元素可压入,则被测序列不是弹出序列。
         如果弹出序列指针已判断完最后一个元素,则被测序列是弹出序列。

4 代码

算法实现:

public class StackPushPopOrder {
    public static boolean validateStackSequences(int[] pushed, int[] popped) {
        // 无效输入
        if (pushed == null || popped == null || pushed.length != popped.length) {
            return false;
        }
        int pushedIndex = 0;
        int poppedIndex = 0;
        // 模拟进栈出栈操作(针对进栈序列)
        Stack stack = new Stack();
        // 弹出序列判断是否结束
        while (poppedIndex < popped.length) {
            // 栈为空或者栈顶元素不等于弹出序列第一个元素,当压入序列不为空,继续将压入序列元素进栈,否则返回false
            if (stack.isEmpty() || (int) stack.peek() != popped[poppedIndex]) {
                if (pushedIndex < pushed.length) {
                    stack.push(pushed[pushedIndex++]);
                } else {
                    return false;
                }
            } else {
                // 栈不为空且栈顶元素等于弹出序列第一个元素,出栈,弹出序列索引后移,继续判断
                stack.pop();
                poppedIndex++;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        int[] push = {1, 2, 3, 4, 5};
        int[] pop1 = {4, 5, 3, 2, 1};
        int[] pop2 = {4, 3, 5, 1, 2};
        System.out.println(validateStackSequences(push, pop1));
        System.out.println(validateStackSequences(push, pop2));
    }
}

参考
在解决本书例题时,参考了一些大佬的题解,比如leetcode上的官方、K神,以及其他的博客,在之后的每个例题详解后都会给出参考的思路或者代码链接,同学们都可以点进去看看!

本例题参考:
https://www.jianshu.com/p/e39ff6a1b3ee

本文如有什么不足或不对的地方,欢迎大家批评指正,最后希望能和大家一起交流进步、拿到心仪的 offer !!!

标签:压入,offer,int,元素,pop,push,弹出,序列
来源: https://blog.csdn.net/qq_41866626/article/details/120524374