剑指offer 面试题22 栈的压入、弹出序列

剑指offer 面试题22 栈的压入、弹出序列

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

package algorithm.foroffer.top30;

import java.util.Arrays;
import java.util.Stack;

/**
 * Created by liyazhou on 2017/5/27.
 * 面试题22:栈的压入、弹出序列
 *
 * 题目:
 *      输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。
 *      假设压入栈的所有数字均不相等。
 *      例如序列 1、2、3、4、5 是某栈的压栈序列,序列 4、5、3、2、1 是该压栈序列对应的一个弹出序列,
 *      但 4、3、5、1、2 就不可能是该压栈序列的弹出序列。
 *
 * 问题:
 *      1. 使用辅助栈
 *      2. 顺序压栈和有条件的出栈操作
 *
 * 思路:
 *      1. 两个序列存储在数组中,创建一个辅助栈(数据结构)
 *      2. 将压入序列的"第一个元素"依次压入到辅助栈中,(算法)
 *          如果辅助栈的栈顶元素和弹出序列的"第一个元素"相等,则从辅助栈弹出该元素;
 *          // 如果辅助栈为空,则继续压入压入序列中为入栈的元素;
 *      3. 辅助栈为空,该弹出序列是压入序列的出栈序列,返回 true;否则两者不匹配,返回 false。
 *         (如果辅助栈栈顶元素和弹出序列的"第一个元素"不相等,而且压入栈没有要压入辅助栈中的元素,返回 false)
 *
 *
 */
public class Test22 {

    public static boolean isPopOrder(int[] pushOrder, int[] popOrder){
        if (pushOrder == null || popOrder == null || pushOrder.length != popOrder.length) return false;

        boolean result = false;
        Stack<Integer> stack = new Stack<>();
        int popNum = 0;
        for (int i = 0; i < pushOrder.length; i++){  // 依次将压入序列中的元素压入到辅助栈
            stack.push(pushOrder[i]);
            // 从辅助栈中弹出和弹出序列中匹配的元素
            while (!stack.isEmpty() && stack.peek() == popOrder[popNum]){
                stack.pop();
                popNum ++;
            }
        }
        if (stack.isEmpty()) result = true;  // 压入序列和弹出序列中的所有的元素都匹配
        return result;
    }


    public static void main(String[] args){
        int[] pushOrder = {1, 2, 3, 4, 5};
        int[][] popOrders = {
                {4, 5, 3, 2, 1},
                {4, 5, 3, 1, 2},
                {4, 5, 3, 1, 6},
        };
        for (int i = 0; i < popOrders.length; i++){
            System.out.print("压入序列:" + Arrays.toString(pushOrder) + "  ");
            System.out.print("弹出序列:" + Arrays.toString(popOrders[i]) + "  ");
            System.out.println(Test22.isPopOrder(pushOrder, popOrders[i]));
        }
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值