Main22 栈的压入、弹出序列

本文介绍如何判断一个序列是否为特定压栈序列的合法弹出序列。通过使用辅助栈并结合输入序列,文章详细阐述了解决方案,并提供了实现代码及测试用例。

剑指Offer_22 栈的压入、弹出序列


2018/6/8 星期五

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

一开始接触到这题,以为,压栈和出栈只存在一个情况。但是这样理解题目存在偏差,因为题目的意思明显是,压栈和入栈是可以交替进行的,比如,当我们压入1,2,3,4的时候,我们可以弹出4,再继续压入5,这样压入的顺序依旧是1,2,3,4,5。但是出栈的顺序就成为了4,5,3,2,1。具体的过程可以参考下表:

步骤操作弹出数字步骤操作弹出数字
1压入16压入1,2,3,5
2压入1,27弹出1,2,35
3压入1,2,38弹出1,23
4压入1,2,3,49弹出12
5弹出1,2,3410弹出1

理解题目的意思之后,我们开始分析。解决这个问题的想法是建立一个辅助栈,把输入的第一个序列中的数子依次压入该辅助栈中,并按照第二个序列的顺序依次从该栈中弹出该数字。判断一个数字是否弹出的标准是:

  1. 如果下一个弹出的元素刚好是栈顶元素,那么直接弹出;
  2. 如果下一个弹出的数字不在栈顶,我们把压栈序列中还没有入栈的数字压入辅助栈,直到把下一个需要弹出的数字压入栈顶为止。
  3. 如果所有的数字都压入栈了仍然没有找到下一个弹出的数字,那么该序列不可能是一个弹出序列。

写下如下代码:

boolean isRight(int[] line1, int[] line2) {
    if (line1 == null || line2 == null) {
        return false;
    }
    int index = 0;
    Stack<Integer> stack = new Stack<>();
    for (int i = 0; i < line2.length && index < line1.length; ) {
        // ①
        if (!stack.isEmpty() && stack.peek() == line2[i]) {
            stack.pop();
            i++;
        } else {
            // ②
            stack.push(line1[index++]);
        }
    }
    // ③
    if (index == line1.length && stack.isEmpty()) {
        return true;
    }
    return false;
}

如果为了使代码更加高效,可以考虑省略其中的stack栈。

测试用例

  1. 功能测试:输入的数字中含有多个数字,或者只有1个数字,第二个序列是或者不是第一个压入序列对应的栈的弹出序列
  2. 特殊输入测试:两个空引用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值