題面:《劍指Offer》P134 / 牛客網
輸入兩個整數序列,第一個序列表示棧的壓入順序,請判斷第二個序列是否爲該棧的彈出順序。假設壓入棧的所有數字均不相等。例如序列1,2,3,4,5是某棧的壓入順序,序列4,5,3,2,1是該壓棧序列對應的一個彈出序列,但4,3,5,1,2就不可能是該壓棧序列的彈出序列。
分析清楚兩個序列的關係問題就能迎刃而解
方法1
第一個彈出棧的位置無限制,假設爲cur。之後元素出棧要更新cur。
此後每一個出棧元素有兩種選擇
1、入棧隊列cur左邊第一個相鄰未出棧的,如4,5,3,2,1中5出棧後,左邊第一個應該是3不能是1,所以序列4,3,5,1,2不對
2、入棧隊列cur右邊未出棧的,不需要相鄰
設置輔助bool列表記錄入棧隊列的元素是否已出棧
bool IsPopOrder(vector<int> pushV, vector<int> popV)
{
int n = popV.size(),cur=0,temp;
if (pushV.size() != n)
return false;
vector<bool> hasPop(n,false);
bool hasFind;
for (int i = 0; i < n; i++)
{
hasFind = false;
temp = cur;
while (cur > 0 && hasPop[cur])//向左查找
cur--;
if (pushV[cur] == popV[i])
{
hasPop[cur] = true;
continue;
}
cur = temp;
for (int j = cur; j < n; j++)//向右遍歷查找
{
if (hasPop[j])
continue;
if (pushV[j] == popV[i])
{
hasPop[j] = true;
cur = j;
hasFind = true;
break;
}
}
if(!hasFind)
return false;
}
return true;
}
方法2
借用輔助棧,根據出棧序列還原出棧過程
如4,5,3,2,1第一個出棧是4,所以在此之前入棧序列1,2,3,4,5中4前面的1,2,3必須先入棧
bool IsPopOrder(vector<int> pushV,vector<int> popV)
{
int n = popV.size(),cur=0;
if (n==0||pushV.size() != n)
return false;
stack<int> s;
for (int data : popV)
{
if (!s.empty() && s.top() == data)
{
s.pop();
continue;
}
if (cur == n)
break;
while (cur < n&&pushV[cur] != data)
s.push(pushV[cur++]);
//s.push(data);
//s.pop();
cur++;
}
return s.empty();
}