OCAC暑期比赛第二场 K题 栈的序列 题解

栈的序列
【题目描述】
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列,但4,3,5,1,2就不可能是该压栈序列的弹出序列。
【输入格式】
第一行为1个整数n(1<=n<=100000),表示序列的长度。  
第二行包含n个整数,表示栈的压入顺序。  
第三行包含n个整数,表示栈的弹出顺序。
【输出格式】
如果第二个序列是第一个序列的弹出序列输出Yes,否则输出No。
【样例输入】
5
1 2 3 4 5
4 5 3 2 1
【样例输出】
Yes
【样例解释】
[1,2,3,4,5] 按照如下顺序进出栈:
push 1
push 2
push 3
push 4
pop // 4
push 5
pop // 5
pop // 3
pop // 2
pop // 1
就能够得到 [4,5,3,2,1]
【数据规模】
50% 的数据,满足 1≤n≤1000;
100%的数据,满足 1≤n≤100000。
【题目分析】
本题涉及的数据结构:栈。
首先我们假设进栈序列是 a[]  数组,出栈序列是 b[] 数组。
现在假设 i 是 a[] 的坐标, j 是 b[] 的坐标。一开始 i==1 , j==1。
那么我们来看,如果 a[i] != a[j],
如果此时栈为空,那么就是说 a[i] 肯定是放进 stack 中没有出来,所以往栈中push(a[i]),同时i++;
不然的话,我们还要判断一下栈顶元素是不是等于 b[j] ,如果是的话,栈pop(),同时j++;
如果不是的话,那还是需要将 a[i] 放到栈中,所以往栈中push(a[i]),同时i++;
依次操作,如果i已经大于n了,并且还需要进行push(a[i])操作,那说明就没有办法达到这个效果,所以就不能这么做了,这个时候就说明没有办法从 a[] 得到 b[] 了。
不然的话,如果我顺序遍历了所有 b[] 中的元素,那么就说明已经可以通过 a[] 转换到 b[] 了。
实现代码如下:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 101000;
int n, a[maxn], b[maxn];

stack<int> stk;

int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i ++) scanf("%d", a+i);
    for (int i = 0; i < n; i ++) scanf("%d", b+i);
    int i = 0, j = 0;
    while (j < n) {
        if (a[i] == b[j]) i++,j++;
        else if (!stk.empty() && stk.top() == b[j]) stk.pop(), j ++;
        else if (i < n) stk.push(a[i++]);
        else {
            puts("No");
            return 0;
        }
    }
    puts("Yes");
    // puts( stk.empty() ? "Yes" : "No" );
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ocac/p/11131676.html
今日推荐