-
题目:
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。
如:假设压入栈的所有数字均不相等。例如序列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; } } }
实现结果: