有这样的题目:
已知从1至n的数字序列,按顺序入栈,每个数字入栈后即可出栈, 也可在栈中停留,等待后面的数字入栈出栈后,该数字再出栈,求该数字序列的出栈序列是否合法?
类似如下:
已知栈的出栈序列为:3 2 5 4 1,判断该栈的出栈序列是否合法
过程如下:
第一次1-5顺序入栈:1,2,3
第二次 3 出栈:1,2
第三次 2 出栈:2
第四次 4,5 入栈:1,4,5
第五次 5 出栈:1,4
第六次 4 出栈:1
第七次 1 出栈:
最终可以得到合法的出栈序列:3 2 5 4 1
而序列:3 1 2 4 5 则不合法
解决方法主要是使用栈和队列来模拟整个过程,是否满足
- 出栈序列存放在队列中:3,2,5,4,1,创建一个临时栈来存放入栈序列(1-5)
- 模拟入栈过程,同时判断入栈后的栈顶是否和队列的对头是否相等;相等则意味着此时该数值合理出栈;否则继续入栈
- 上过程结束后,若临时栈或者队列中仍然存在元素,则该出栈序列不合法
具体过程如下:
初始:
queue: 3 2 5 4 1
stack:
第一次:3 2 5 4 1
stack:1
第二次:
queue: 3 2 5 4 1
stack: 1,2
第三次:
queue: 2 5 4 1
stack: 1,2
第四次:
queue 2 5 4 1
stack: 1,2,4
…
最后一次:
queue: 1
stack :1
实现代码如下:
bool judge_formal_seq(queue<int> order){
stack<int> seq;
int num = order.size();
if (order.empty()) {
return false;
}
for (int i = 1; i <= 5; ++i) {
seq.push(i);
/*判读队头元素和栈顶元素是否相等,相等则认为该元素可以出栈,两者都pop*/
while (!seq.empty() && order.front() == seq.top()) {
order.pop();
seq.pop();
}
}
if(seq.empty()) {
return true;
} else {
return false;
}
}
测试代码如下:
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
using namespace std;
bool judge_formal_seq(queue<int> order){
stack<int> seq;
int num = order.size();
if (order.empty()) {
return false;
}
for (int i = 1; i <= 5; ++i) {
seq.push(i);
while (!seq.empty() && order.front() == seq.top()) {
order.pop();
seq.pop();
}
}
if(seq.empty()) {
return true;
} else {
return false;
}
}
int main() {
queue<int> order;
int tmp;
cout << "construct the exit stack seq :" << endl;
for (int i = 0; i < 5; ++i){
cin >> tmp;
order.push(tmp);
}
cout << "judge the stack seq is " << (judge_formal_seq(order)?"true":"false") << endl;
return 0;
}
输出如下:
construct the exit stack seq :
3 2 5 4 1
judge the stack seq is true
construct the exit stack seq :
3 1 2 5 4
judge the stack seq is false