剑指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();
}
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列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();
}
相关文章推荐
- C++基于栈实现铁轨问题
- 浅析C语言中堆和栈的区别
- C语言栈的表示与实现实例详解
- C语言实现颠倒栈的方法
- 算法系列15天速成 第十天 栈
- 一看就懂:图解C#中的值类型、引用类型、栈、堆、ref、out
- Array栈方法和队列方法的特点说明
- java数据结构之java实现栈
- 浅析栈区和堆区内存分配的区别
- 用Java代码实现栈数据结构的基本方法归纳
- 用PHP解决的一个栈的面试题
- 浅谈C#中堆和栈的区别(附上图解)
- C#使用Object类实现栈的方法详解
- JavaScript数据结构与算法之栈详解
- C语言之栈和堆(Stack && Heap)的优缺点及其使用区别
- Python实现栈的方法
- JavaScript数组的栈方法与队列方法详解
- JavaScript数据结构与算法之栈与队列
- JavaScipt中栈的实现方法
- Java中堆和栈的区别详解