棧的壓入、彈出序列
題目
輸入兩個整數序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否可能爲該棧的彈出順序。假設壓入棧的所有數字均不相等。例如序列1,2,3,4,5是某棧的壓入順序,序列4,5,3,2,1是該壓棧序列對應的一個彈出序列,但4,3,5,1,2就不可能是該壓棧序列的彈出序列。(注意:這兩個序列的長度是相等的)
https://www.nowcoder.com/practice/d77d11405cc7470d82554cb392585106?tpId=13&&tqId=11174&rp=2&ru=/activity/oj&qru=/ta/coding-interviews/question-ranking
題解
這道題我們可以使用笨點的方法列舉出所有彈出序列然乎一一比較判斷,但是這樣的實現方法事件複雜度很高,並不高效,於是採用以下的解法,只需要O(n)的時間複雜度。
1、首先我們初始化入棧序列和出棧序列和一個空棧,並用兩個指針ptr1 ptr2
首先指向兩個序列的第一個元素。
2、只要棧爲空或者當前棧頂元素與出棧序列中ptr2
所指的元素不相同,則將入棧序列中ptr1
所指的元素壓入棧,並將ptr1
後移。
3、如果當前棧頂元素與出棧序列中ptr2
所指元素相同,則將當前棧頂元素出棧,並將ptr2
後移。
4、重複第2第3步,如果ptr2
可以遍歷完出棧序列,則說明出棧序列是該棧的一個彈出順序。如果ptr1
中的入棧元素已經全部壓入棧但是棧頂元素依然與出棧序列中ptr2
所指元素不相同,還需要入棧,則說明出棧序列不是該棧的一個彈出順序。
代碼實現
class Solution {
public:
bool IsPopOrder(vector<int> pushV,vector<int> popV) {
int pushi = 0, popi = 0;
stack<int> sta;
while(popi < popV.size())
{
if(sta.empty() || (sta.top() != popV[popi]))
{
if(pushi < pushV.size())
{
sta.push(pushV[pushi]);
pushi++;
}
else
{
return false;
}
}
else
{
sta.pop();
popi++;
}
}
return true;
}
};