题目: 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
栈的知识回顾:先进后出,所以如果我们入栈的顺序是1,2,3,4,5, 虽然在入栈的过程中可以任意出栈,但是我们没发做到 3,1,2,4,5, 原因在于1比2先入栈,并且之后的3也入栈了,所以我们不能得到3,1,2的序列。
构造辅助栈,解决这个问题:
- 第一个数组为入栈数组,
- 第二个数组为出栈数组,
我们入栈之前先做一个判断,栈顶元素和我出栈数组的当前元素相等吗?如果相等我们就出栈,出栈数组指针后移。如果不等,我们只能继续入栈了。那我们的退出条件是什么呢?正常匹配的时候很简单,我们的栈空了,出栈数组也刚好判断完。然后不匹配的时候呢?既没有元素可入栈了,也没有匹配的元素出栈了,对吧?
那我们一起看代码:
/// <summary>
/// 判断入栈的序列是否能够得到某个出栈序列
/// </summary>
/// <param name="pushSequence">入栈序列</param>
/// <param name="popSequence">出栈序列</param>
/// <returns>True/能, false/不能</returns>
public static bool IsPopSequence(int[] pushSequence, int[] popSequence)
{
// 当两个序列都不空,且长度相等的时候,才有意义,否则都表示不可能
if (pushSequence != null && popSequence != null && pushSequence.Length == popSequence.Length)
{
// 申明一个栈
Stack<int> myStack = new Stack<int>();
// 两个指针,一个指向入栈序列,一个指向出栈序列
int pushIndex = 0;
int popIndex = 0;
// 当入栈序列没有扫描完,或者出栈数列里还有没匹配完的序列,我们就继续
while (pushIndex < pushSequence.Length || popIndex < popSequence.Length)
{
// 判断栈顶元素是否与当前出栈的元素一致,
// 若是我们就出栈,出栈序列后移一位,等待下一次比较
if (myStack.Count > 0 && myStack.First() == popSequence[popIndex])
{
myStack.Pop();
popIndex++;
}
// 否则,我们就只能入栈了
else
{
// 还有元素入栈么?如果有,那以后或许还有机会,我们先进栈,再等待下一次进栈
if (pushIndex < pushSequence.Length)
{
myStack.Push(pushSequence[pushIndex]);
pushIndex++;
}
// 若没有元素可以进栈了,说明我们失败了,
// 说明所有的元素都已经入过栈了,可以依旧没有匹配出栈的序列
// 跳出循环吧
else
{
break;
}
}
}
// 我们再判断依次,当栈为空,出栈序列都比较完,说明完全匹配
return myStack.Count == 0 && popIndex == popSequence.Length;
}
return false;
}
我们一起测试一下:
好了,我们这道题就先聊到这哈。感兴趣的同学可以加我们的QQ群参与讨论,微信公众号获取更多资讯。还欢迎大家访问我的视频教程,了解更多经典面试题。