題目:輸入兩個整數序列。其中一個序列表示棧的push 順序,
判斷另一個序列有沒有可能是對應的pop 順序。
如果我們希望pop 的數字正好是棧頂數字,直接pop 出棧即可;
如果希望pop 的數字目前不在棧頂,我們就到
push 序列中還沒有被push 到棧裏的數字中去搜索這個數字,
並把在它之前的所有數字都push 進棧。
如果所有的數字都被push 進棧仍然沒有找到這個數字,表明該序列不可能是一個pop 序列。
我們來着重分析下此題:
push 序列已經固定,
push pop
--- -- -> /---->
5 4 3 2 1 / 4 5 3 2 1
| 5 |
| 4 |
| 3 |
| 2 |
|1 |
1.要得到4 5 3 2 1 的pop 序列,即pop 的順序爲4->5->3->2->1
首先,要pop4,可讓push5 之前,pop4,然後push5,pop5
然後發現3 在棧頂,直接pop 3..2..1
2.再看一序列,
push pop
--- -- -> /---->
5 4 3 2 1 / 4 3 5 1 2
| 5 |
| 4 |
| 3 |
| 2 |
|___1__|
想得到4 3 5 1 2 的pop 序列,是否可能? 4->3->5->1->2
同樣在push5 之前,push 了4 3 2 1,pop4,pop 3,然後再push 5,pop5
2
再看棧中的從底至上是1 ,由於1 2 已經在棧中,所以只能先pop2,才能pop1。
所以,很顯然,不可能有4 3 5 1 2 的pop 序列。
所以,當我要pop 一個數時,先看這個數在不在已經push 的棧頂,如果,在,好,直接pop 它。
如果,不在,那麼,從push 序列中,去找這個數,找到後,push 它進棧,
如果push 隊列中它的前面還有數,那麼還得把它前面數,先push 進棧。
如果push隊列中沒有這個數,那當然就不是存在這個pop 結果了。
我自已寫的代碼 ,主要用了C++中的容器list和stack,避免使用指針而出錯,不過,指針還是要好 好學習啊!
#include<iostream> #include<list> #include<stack> using namespace std;
bool Ispoporder(list<int> pushlist,list<int> poplist) { if(pushlist.empty()||poplist.empty()) return false; stack<int> s; for(list<int>::iterator iter=poplist.begin();iter!=poplist.end();iter++) { if(!s.empty()&&(*iter)==s.top()) s.pop(); else { //list<int>::iterator it=index(pushlist,*iter); list<int>::iterator it=pushlist.begin(); while(it!=pushlist.end()) { if((*it)!=(*iter)) it++; else break; } //此while循 環是list的查找,可以直接用stl裏的查找算法; if(it==pushlist.end()) return false; else { list<int>::iterator it1=pushlist.begin(); while(it1!=it) { s.push(*it1); it1++; pushlist.pop_front(); } s.push(*it); pushlist.pop_front(); } s.pop(); }
} return true;
}
int main() { list<int> pushlist; list<int> poplist; int a[5]={1,2,3,4,5}; int b[5]={4,3,5,1,2}; for(int i=0;i<5;i++) pushlist.push_back(a[i]); for(int i=0;i<5;i++) poplist.push_back(b[i]); if(Ispoporder(pushlist,poplist)) cout<<"is"; else cout<<"is not"; }