题解
问题描述
给出两个序列 pushed
和 poped
,分别表示入栈和出栈操作的顺序。我们需要判断给定的出栈序列是否可能对应于给定的入栈序列。如果可能,则输出 “Yes”;否则,输出 “No”。
解题思路
-
读取输入:读取询问次数
q
和每次询问的入栈和出栈序列。 -
模拟栈操作:通过使用一个栈(
s1
)和一个队列(s2
),我们可以模拟栈的入栈和出栈操作。
a. 入栈操作:按顺序遍历入栈序列pushed
,每次将元素推入栈s1
。
b. 出栈操作:每次入栈后,检查栈顶元素是否与队列s2
的前端元素相匹配。如果匹配,则从栈和队列中弹出元素,并继续检查下一个元素,直到不匹配或栈为空。 -
检查结果:如果所有出栈元素都被成功弹出,则输出 “Yes”。否则,输出 “No”。
-
清理数据结构:为下一次查询准备,确保栈和队列为空。
原始代码的错误
原始代码中的错误在于缺乏对连续出栈操作的处理。在模拟过程中,可能存在连续几个元素需要出栈的情况,但原始代码在每次入栈后只执行了一次出栈操作。这意味着对于某些入栈和出栈序列组合,代码可能在执行完所有的入栈操作后仍然留有未匹配的出栈元素。
错误代码部分:
for(int i=0;i<n;i++) {
s1.push(pushed[i]);
if(!s1.empty() && s1.top() == s2.front()) {
s2.pop();
s1.pop();
}
}
修正
修正代码主要在于增加一个内部循环,其实是把原先 if
语句改成 while
循环,用于在每次入栈后连续检查栈顶元素与队列头部元素的匹配,直到不匹配或栈为空。
修正的代码块:
for(int i=0;i<n;i++) {
s1.push(pushed[i]);
while(!s1.empty() && s1.top() == s2.front()) {
s2.pop();
s1.pop();
}
}
复杂度分析
时间复杂度:O(n),空间复杂度:O(n)。
代码简洁化
经过这一修正,原始代码中的第二个 while
循环成为多余,并被删除。最终的代码版本更精简,也更符合问题描述中的逻辑。
最终版本的完整代码:
#include<bits/stdc++.h>
using namespace std;
int pushed[100005];
int poped[100005];
stack<int> s1;
queue<int> s2;
int main() {
int q;
cin>>q;
while(q--) {
int n;
cin>>n;
for(int i=0;i<n;i++) {
cin>>pushed[i];
}
for(int i=0;i<n;i++) {
cin>>poped[i];
s2.push(poped[i]);
}
for(int i=0;i<n;i++) {
s1.push(pushed[i]);
while(!s1.empty() && s1.top() == s2.front()) {
s2.pop();
s1.pop();
}
}
if(s1.empty())
cout<<"Yes"<<endl;
else
cout<<"No"<<endl;
while(!s1.empty()) s1.pop();
while(!s2.empty()) s2.pop();
}
return 0;
}
这个版本的代码更精简,也更符合问题描述中的逻辑。