[2021校招必看之Java版《剑指offer》-21] 栈的压入、弹出序列

1、题目描述

  【JZ21】输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
  知识点:栈
  难度:☆

2、解题思路

  本题的意思是说:已知一个入栈序列,入栈顺序和序列的顺序已知,问另一个序列的顺序是否可能的出栈顺序。例如,已知一个入栈序列为{1,2,3,4},操作顺序是:入栈、入栈、入栈、出栈、入栈、出栈、出栈、出栈。那么此时的出栈顺序为{3,4,2,1}。即序列{3,4,2,1}{1,2,3,4}的可能的弹出顺序。
  题意要求判断对于一个给定入栈顺序的序列,判断另一个序列是否为它的可能出栈序列。
  以下PushA为入栈序列,PopA为出栈序列。
  根据栈的先进后出原则,如果入栈序列是全部入栈后再出栈,那么我们只需要判断两个序列是否顺序相反即可,但现在的情况是,在入栈过程中可能有些元素会在中间出栈,因此,我们不能简单判断序列顺序相反,而是要遍历两个序列,一步步检查是否符合要求。
  先假设PopA就是PushA的一个出栈序列,然后一步步判断它是否满足出栈序列的要求。
  我们定义两个指针indexPushAindexPopA分别表示入栈序列和出栈序列的索引。
  1、初始化时两个指针都为0;
  2、如果pushA[indexPushA] != popA[indexPopA], 那么应该将pushA[indexPushA]放入栈中, indexPushA++
  3、否则,pushA[indexPushA] == popA[indexPopA], 说明这个元素是放入栈中立马弹出,所以,indexPushA++, indexPopA++,然后应该检查popA[indexPopA]与栈顶元素是否相等,如果相等,indexPopA++, 并且弹出栈顶元素
  4,重复2,3, 如果indexPushA > pushA.length, 说明入栈序列访问完,此时检查栈是否为空,如果为空,说明匹配,否则不匹配。

3、解题代码

package pers.klb.jzoffer.medium;

import java.util.Stack;

/**
 * @program: JzOffer2021
 * @description: 栈的压入、弹出序列
 * @author: Meumax
 * @create: 2020-07-10 10:47
 **/
public class PopOder {

    public boolean IsPopOrder(int[] pushA, int[] popA) {
        Stack<Integer> stack = new Stack<Integer>();
        int indexPushA = 0; // 入栈序列的指针
        int indexPopA = 0;  // 出栈序列的指针

        while (indexPushA < pushA.length) {
            if (pushA[indexPushA] == popA[indexPopA]) { // 入栈马上又出栈
                // 这里就省略入栈马上出栈的操作,等同于两个指针都往后移动一位
                indexPushA++;
                indexPopA++;
                // 再判断此时的popA[indexPopA]是否刚好在栈顶
                // 如果是,说明该元素就是在中间出栈的,而不是全部入栈完再出栈的
                while (!stack.isEmpty() && stack.peek() == popA[indexPopA]) {
                    stack.pop();
                    indexPopA++;
                }
            } else {  // 入栈,在后面出栈
                stack.push(pushA[indexPushA]);
                indexPushA++;
            }
        }

        return stack.isEmpty();
    }
}

4、解题心得

  本题的技巧在于遍历入栈序列和出栈序列,当遍历到的两个元素相同,说明它是刚入栈就出栈,如果不是,则说明是在后面出栈,我们就把他入栈。在出栈了一个元素之后,继续判断pop序列的当前元素是不是在栈顶,如果是,则继续出栈。当最后栈没有元素了,说明这个pop序列就是push序列的一个可能的出栈序列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值