• 剑指Offer_栈的压入序列是否有对应的弹出序列


    • 题目:

    输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。

    如:假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列。

    但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

    • 解题思路:

    建一个临时栈,将输入序列pushA[]的数据依次往栈中压,每进一个都跟popA[]中第一个位置的数比较,

    若相同,则弹出,然后继续压入,同时跟popA[]第二个位置的数比较,若相同,则弹出,下一个压入的数和popA[]第三个位置的数比较,

    依次进行下去,若到最后,临时栈内的数都能弹出,则说明,该popA[]是pushA[]的一个弹出序列,文字描述比较空洞,下面详细列举每个步骤的结果:

    设有栈 Stack<Integer> temp = new Stack<Integer>();  弹出序列的下标int popIndex = 0;

    pushA[] = {1,2,3,4,5};popA[] = {4,5,3,2,1};

    (1)1压入,与 popA[popIndex]比较,1!=4;不弹出,继续压入;

    (2)2压入,与 popA[popIndex]比较,2!=4;不弹出,继续压入;

    (3)3压入,与 popA[popIndex]比较,3!=4;不弹出,继续压入;

    (4)4压入,与 popA[popIndex]比较,4==4;4弹出,popIndex 后移一位,popIndex = popIndex + 1 = 1;   

    (5)5压入,与 popA[popIndex]比较,5==5;5弹出,popIndex 后移一位,popIndex = popIndex + 1 = 2;   //五个数都依次进了栈

    (6)5弹出后,栈顶元素为3,3与 popA[popIndex]比较,3==3;3弹出,popIndex 后移一位,popIndex = popIndex + 1 = 3;   

    (7)3弹出后,栈顶元素为2,2与 popA[popIndex]比较,2==2;2弹出,popIndex 后移一位,popIndex = popIndex + 1 = 4;   

    (8)2弹出后,栈顶元素为1,1与 popA[popIndex]比较,1==1;1弹出,popIndex 后移一位,popIndex = popIndex + 1 = 5;   

    至此,临时栈内所有元素都弹出了,栈为空,则表明pupA[]是popA[]的一个弹出序列;

    若popA [] = {4,5,3,1,2}; 则情况为:

    (1)1压入,与 popA[popIndex]比较,1!=4;不弹出,继续压入;

    (2)2压入,与 popA[popIndex]比较,2!=4;不弹出,继续压入;

    (3)3压入,与 popA[popIndex]比较,3!=4;不弹出,继续压入;

    (4)4压入,与 popA[popIndex]比较,4==4;4弹出,popIndex 后移一位,popIndex = popIndex + 1 = 1;   

    (5)5压入,与 popA[popIndex]比较,5==5;5弹出,popIndex 后移一位,popIndex = popIndex + 1 = 2;   //五个数都依次进了栈

    (6)5弹出后,栈顶元素为3,3与 popA[popIndex]比较,3==3;3弹出,popIndex 后移一位,popIndex = popIndex + 1 = 3;   

    (7)3弹出后,栈顶元素为2,2与 popA[popIndex]比较,2!=1;2不弹出;2一直都不能弹出,所以该栈一直处于有数据的状态,则popA[]不是pushA[]的弹出序列;

    • 代码实现(Java):

    /**
     * 
     */
    package com.cherish.SwordRefersToOffer;
    
    import java.util.Stack;
    
    /**
     * @author acer
     *题目:
     *输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。
     *假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列
     *,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
     *
     *
     */
    public class test_31_栈的压入和弹出序列 {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO 自动生成的方法存根
            int[] pushA = {1,2,3,4,5};
            int[] popA = {4,5,3,2,1};
            System.out.println(IsPopOrder(pushA,popA));
        }
        
        
        
        public static boolean IsPopOrder(int [] pushA,int [] popA) {
             if(pushA.length == 0||popA.length == 0)
             {
                 return false;
             }
             Stack<Integer> temp = new Stack<Integer>();
             //用于标识弹出序列的位置
             int popIndex = 0;
             for(int i = 0;i<pushA.length;i++)
             {
                 temp.push(pushA[i]);
                 //如果栈不为空,且栈顶元素等于弹出序列
                 while(!temp.empty()&&temp.peek() == popA[popIndex])
                 {
                     //出栈
                     temp.pop();
                     //弹出序列向后一位
                     popIndex++;
                 }
             }
             return temp.empty();
        }
        
    }

    运行结果:

     

    • 代码实现(C#):

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace test_31_栈的压入和弹出序列
    {
        class Program
        {
            static void Main(string[] args)
            {
                int[] pushV = { 1, 2, 3, 4, 5 };
                int[] popV = { 4, 5, 3, 2, 1};
    
    
                Console.WriteLine(IsPopOrder(pushV,popV));
                Console.ReadLine();
            }
    
    
            public static bool IsPopOrder(int[] pushV, int[] popV)
            {
                // write code here
                if (pushV.Length == 0|| popV.Length == 0)
                {
                    return false;
                }
                var stack = new Stack<int>();
                int popIndex = 0;
                for (int i = 0; i < pushV.Length; i++)
                {
                    stack.Push(pushV[i]);
                    while (stack.Count > 0 && stack.Peek().Equals(popV[popIndex]))
                    {
                        stack.Pop();//弹出栈顶元素
                        popIndex++;//popV下标后移一位
                    }
                }
                return stack.Count() == 0;
              
            }
        }
    }

    实现结果:

     

  • 相关阅读:
    [Swift]LeetCode300. 最长上升子序列 | Longest Increasing Subsequence
    备忘录模式之C++实现
    leecode 题解 || Merge k Sorted Lists 问题
    数学三大危机
    singlefile.py
    Data Url生成工具之HTML5 FileReader实现
    算法题:打印1到最大的n位数
    java.lang.NoClassDefFoundError: org/apache/commons/lang/xwork/StringUtils
    hdu 1181 变形课
    postgis经常使用函数介绍(一)
  • 原文地址:https://www.cnblogs.com/CherishTheYouth/p/CherishTheYouth_2019_0814_StackPushAndPop.html
Copyright © 2020-2023  润新知