您的位置:首页 > 职场人生

剑指Offer-面试题22:栈的压入、弹出序列

2016-06-30 18:46 351 查看
题面:《剑指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();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: