首页 > 代码库 > 【编程题目】栈的 push、pop 序列
【编程题目】栈的 push、pop 序列
29.栈的 push、pop 序列(栈)
题目:输入两个整数序列。其中一个序列表示栈的 push 顺序,
判断另一个序列有没有可能是对应的 pop 顺序。
为了简单起见,我们假设 push 序列的任意两个整数都是不相等的。
比如输入的 push 序列是 1、2、3、4、5,那么 4、5、3、2、1 就有可能是一个 pop 系列。
因为可以有如下的 push 和 pop 序列:
push 1,push 2,push 3,push 4,pop,push 5,pop,pop,pop,pop,
这样得到的 pop 序列就是 4、5、3、2、1。
但序列 4、3、5、1、2 就不可能是 push 序列 1、2、3、4、5 的 pop 序列。
思路:
首先,我记录了每个pop序列中每一个元素对应在push序列中的位置。这就像是把push序列强制成0 1 2 3 4...一样,这样push序列就是从小到大排列的了。
然后,观察从小到大排列的push序列,其合理的pop序列的特点。
4 5 3 2 1
记录第1个数字 并查找递增的数字 这里是 4 5 他们是递增的。
3 4 2 1 5
3 4 5 递增的
发现只要这些数字符合递增规律,那么pop序列就是合理的。且这些序列就是新加入数字后开始弹出的值。
还是拿3 4 2 1 5举例
3 是在压入1 2 3后弹出的第一个值
4 是在压入4后弹出的第一个值
5 是在压入5后弹出的第一个值
4 2 1这个递减的序列表示,没有压入新值,一直在弹出。
即,有递增序列表示有压入新的值,递减序列表示一直弹出。因为push序列时递增的,故压入的新值只能越来越大。
对于4、3、5、1、2
4 5 2 显然不满足递增关系 即压入5后不能再压入2 不是合法的pop序列
注:我没法证明,不知道是不是所有的都符合这个规律。谁能举出反例吗?
/*29.栈的 push、pop 序列(栈)题目:输入两个整数序列。其中一个序列表示栈的 push 顺序,判断另一个序列有没有可能是对应的 pop 顺序。为了简单起见,我们假设 push 序列的任意两个整数都是不相等的。 比如输入的 push 序列是 1、2、3、4、5,那么 4、5、3、2、1 就有可能是一个 pop 系列。因为可以有如下的 push 和 pop 序列:push 1,push 2,push 3,push 4,pop,push 5,pop,pop,pop,pop,这样得到的 pop 序列就是 4、5、3、2、1。但序列 4、3、5、1、2 就不可能是 push 序列 1、2、3、4、5 的 pop 序列。start time = 16:15end time = 17:20 */#include <stdio.h>int * getlocation(int data, int * poplist, int len){ for(int i = 0; i < len; i++) { if(data =http://www.mamicode.com/= poplist[i]) return poplist + i; } return NULL;}bool ispop(int * pushlist, int * poplist, int len){ for(int i = 0; i < len; i++) //记录pop中的数字对应push中那个位置 { int * loc = getlocation(pushlist[i], poplist, len); if(loc != NULL) { *loc = i; } else { printf("error:the two list have different member!"); } } int IncreaseNum2 = poplist[0]; int IncreaseNum1; for(int i = 1; i < len; i++) { if(poplist[i] > poplist[i - 1]) { IncreaseNum1 = IncreaseNum2; IncreaseNum2 = poplist[i]; if(IncreaseNum2 < IncreaseNum1) return false; } } return true;}int main(){ int a[5] = {1,2,3,4,5}; int b[5] = {5,3,4,2,1}; bool is = ispop(a, b, 5); return 0;}
网上答案:网上的思路惊人的一致,都是直接的建一个栈来模拟这个过程。比我的思路来的要好,计算少,又好理解。
http://blog.sina.com.cn/s/blog_a46817ff01019vtd.html
如果我们希望pop的数字正好是栈顶数字,直接pop出栈即可;如果希望pop的数字目前不在栈顶,我们就到push序列中还没有
* 被push到栈里的数字中去搜索这个数字,并把在它之前的所有数字都push进栈。如果所有的数字都被push进栈仍然没有找到这
* 个数字,表明该序列不可能是一个pop序列。
网上随便找了个代码,还没验证http://www.cnblogs.com/aLittleBitCool/archive/2011/03/05/1971689.html
//栈的push、pop序列#include<iostream>#include<stack>const int SIZE=5; //定义长度using namespace std;bool judge(int Spush[],int Spop[]){ stack<int> my_stack; int iPush=0,iPop=0; while(iPush<SIZE){ //当栈顶和pop相等时,将pop后的栈顶与pop之后的元素相比,直到不等 cout<<"push "<<Spush[iPush]<<endl; //测试 my_stack.push(Spush[iPush]); while(!my_stack.empty()&&iPop!=5&&my_stack.top()==Spop[iPop]){ //小心数组越界 cout<<"pop "<<Spop[iPop]<<endl; //测试 iPop++; my_stack.pop(); } iPush++; } if(iPop==SIZE) return true; else return false;}int main(void){ int Spush[SIZE],Spop[SIZE]; for(int i=0;i<SIZE;i++) cin>>Spush[i]; for(int i=0;i<SIZE;i++) cin>>Spop[i]; if(judge(Spush,Spop)) cout<<"Yes"<<endl; else cout<<"No"<<endl; system("pause"); return 0;}
【编程题目】栈的 push、pop 序列