標籤:style blog http color io os ar for div
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 == 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 序列