面试题 22,栈的压入,弹出序列

思路:边界情况是输入队列为空。我的想法是,弹出序列必然在原序列上是逐个移动的,例如:如果弹出的第一个为3,那么下一个可以为2,也可以为4。为2表示弹出3后,没有压栈,继续弹出,为4表示又压入4再将4弹出。无论弹出2还是弹出4,下一弹出的又必须是其相邻的。比如弹出2,下一步要么弹出4,要么弹出1;弹出4的话,下一步要么弹出2,要么弹出5。如果出现“跳跃”,也就是弹出的数字不是当前数字的相邻位,就说明该弹出序列不满足要求。
为此,我定义了一个符号序列flag[],其长度和压栈序列相同,凡是弹出的会被置为false,函数prev()返回压栈序列里前一个不是false的,next()返回压栈序列里后一个不是false的。
代码:
#include <stdio.h> int prev(bool *flag, int pushLength, int current){ do { current--; if(current < 0 || current >= pushLength) return -1; }while(flag[current] == false); return current; } int next(bool *flag, int pushLength, int current){ do { current++; if(current < 0 || current >= pushLength) return -1; }while(flag[current] == false); return current; } bool IsPopOrder(const int* push, const int* pop, unsigned int pushLength, unsigned int popLength){ if(popLength > pushLength) return false; if(pushLength == 0 || popLength == 0) return false; bool *flag = new bool[pushLength]; int i = 0; for(i = 0;i < pushLength;i++){ flag[i] = true; } int current = -1; for(i = 0;i < pushLength; i++){ if(push[i] == pop[0]){ current = i; } } if(current == -1) return false; for(int i = 1;i < popLength;i++){ flag[current] = false; int temp = current; int prevIte = prev(flag, pushLength, current); int nextIte = next(flag, pushLength, current); if(prevIte != -1 && push[prevIte] == pop[i]) current = prevIte; if(nextIte != -1 && push[nextIte] == pop[i]) current = nextIte; if(current == temp) return false; } return true; } int main(){ int array1[] = {1,2,3,4,5,6}; int array2[] = {3,4,5,6,2,1}; printf("The order is %s", IsPopOrder(array1, array2, 6, 6) ? "valid" : "invalid"); }
书中的思路是:定义一个栈,从而模拟整个序列的压入和弹出。在弹出序列每读到一个值,如果其不在栈顶,就将压入序列中这个值,以及之前的值都一起压入栈中。弹出这个值。
返回false的条件是,所读入的弹出序列中的值既不在栈顶,又不在压入序列中。
书中代码:
#include "stdafx.h" #include <stack> bool IsPopOrder(const int* pPush, const int* pPop, int nLength) { bool bPossible = false; if(pPush != NULL && pPop != NULL && nLength > 0) { const int* pNextPush = pPush; const int* pNextPop = pPop; std::stack<int> stackData; while(pNextPop - pPop < nLength) { // 当辅助栈的栈顶元素不是要弹出的元素 // 先压入一些数字入栈 while(stackData.empty() || stackData.top() != *pNextPop) { // 如果所有数字都压入辅助栈了,退出循环 if(pNextPush - pPush == nLength) break; stackData.push(*pNextPush); pNextPush ++; } if(stackData.top() != *pNextPop) break; stackData.pop(); pNextPop ++; } if(stackData.empty() && pNextPop - pPop == nLength) bPossible = true; } return bPossible; }
------------------------------------------------
Felix原创,转载请注明出处,感谢博客园!
posted on 2014-01-20 08:49 Felix Fang 阅读(190) 评论(0) 收藏 举报
浙公网安备 33010602011771号