算法训练第二期栈

2次阅读

共计 2947 个字符,预计需要花费 8 分钟才能阅读完成。

PAT 甲级 1051

题目描述

1051 Pop Sequence (25 分)

Given a stack which can keep M numbers at most. Push N numbers in the order of 1, 2, 3, …, N and pop randomly. You are supposed to tell if a given sequence of numbers is a possible pop sequence of the stack. For example, if M is 5 and N is 7, we can obtain 1, 2, 3, 4, 5, 6, 7 from the stack, but not 3, 2, 1, 7, 5, 6, 4.

Input Specification:

Each input file contains one test case. For each case, the first line contains 3 numbers (all no more than 1000): M (the maximum capacity of the stack), N (the length of push sequence), and K (the number of pop sequences to be checked). Then K lines follow, each contains a pop sequence of N numbers. All the numbers in a line are separated by a space.

Output Specification:

For each pop sequence, print in one line “YES” if it is indeed a possible pop sequence of the stack, or “NO” if not.

Sample Input:

5 7 5
1 2 3 4 5 6 7
3 2 1 7 5 6 4
7 6 5 4 3 2 1
5 6 4 3 7 2 1
1 7 6 5 4 3 2

Sample Output:

YES
NO
NO
YES
NO

思路

主要思路

将 1~ n 一次入栈,在入栈的过程中如果入栈的元素恰好等于出栈的序列当前等待出栈的元素,则让其出栈,同时把栈序列当前等待的元素位置标记后移一位。此时,只要栈顶元素仍然等于出栈序列当前等待元素,则持续出栈。

步骤

  1. 初始化栈,用 bool 变量 flag 来标记出栈序列是否合法(是否相等)。使用 int current 来标记当前等待的元素。
  2. 由于入栈的顺序为 1 ~ n。所以从 1 到 n 枚举 i,对每一个 i,现将 i 入栈。若此时栈内元素数目大于 m, 则违反规则,并置 flag == false。否则反复判断当前 current 所指出栈序列中的元素是否等于栈顶元素,若是,则让其出栈,并让 count 自增。
  3. flag == false 则输出 YES。反之输出 NO。

代码

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stack>

using namespace std;

const int maxn = 1010;
stack<int> S;
int arr[maxn];
int main() {
    int m, n, T;
    scanf("%d%d%d", &m, &n, &T);
    while (T--) {while (!S.empty())    S.pop();
        for (int i = 1; i <= n; i++) {scanf("%d", &arr[i]);
        }
        int current = 1;
        bool flag = true;
        for (int i = 1; i <= n; i++) {S.push(i);
            if (S.size() > m) {
                flag = false;
                break;
            }
            while (!S.empty() && S.top() == arr[current]) {S.pop();
                current++;
            }
        }
        if (S.empty() == true && flag == true) {printf("YES\n");
        }
        else {printf("NO\n");
        }
    }
    return 0;
}

LeetCode 栈排序

题目描述

面试题 03.05. 栈排序

难度中等 11

栈排序。编写程序,对栈进行排序使最小元素位于栈顶。最多只能使用一个其他的临时栈存放数据,但不得将元素复制到别的数据结构(如数组)中。该栈支持如下操作:pushpoppeekisEmpty。当栈为空时,peek 返回 -1。

示例 1:

 输入:["SortedStack", "push", "push", "peek", "pop", "peek"]
[[], [1], [2], [], [], []]
 输出:[null,null,null,1,null,2]

示例 2:

 输入:["SortedStack", "pop", "pop", "push", "pop", "isEmpty"]
[[], [], [], [1], [], []]
 输出:[null,null,null,null,null,true]

说明:

  1. 栈中的元素数目在 [0, 5000] 范围内。

思路

要求不能用别的,只能用栈,那就使用一个主栈和一个辅助栈。

先给主栈压栈,如果主栈里面已经有元素了就要比大小。如果原来的元素大,则直接压栈。否则把原来的元素压到辅助栈中,比较下一个,以此类推直到比到比新元素大旧元素,然后压栈,再把辅助栈中的元素放回来。持续以上步骤,直至结束。

代码

//AC 程序 1
class SortedStack {
private:
    stack<int>s1;// 原栈为升序
    stack<int>s2;// 辅助栈为降序
public:
    SortedStack() {}
    
    void push(int val) {while(!s2.empty()&&s2.top()>val){// 辅助栈中存在比 val 大的值
            s1.push(s2.top());
            s2.pop();}
        while(!s1.empty()&&s1.top()<val){// 原栈中有比 val 小的值
            s2.push(s1.top());
            s1.pop();}
        s1.push(val);
    }
    
    void pop() {while(!s2.empty()){// 清空辅助栈
            s1.push(s2.top());
            s2.pop();}
        if(!s1.empty()) s1.pop();}
    
    int peek() {while(!s2.empty()){// 清空辅助栈
            s1.push(s2.top());
            s2.pop();}
        if(!s1.empty()) return s1.top();
        else return -1;
    }
    
    bool isEmpty() {return s1.empty()&&s2.empty();}
};
//AC 程序 2
class SortedStack {
public:
    stack<int> data,as;
    SortedStack() {}
    
    void push(int val) {while(!data.empty()&&data.top()<val){as.push(data.top());
            data.pop();}
        data.push(val);
        while(!as.empty()){data.push(as.top());
            as.pop();}
    }
    
    void pop() {if(data.size())
            data.pop();}
    
    int peek() {if(data.size())
        return data.top();
        return -1;
    }
    
    bool isEmpty() {return data.empty();
    }
};
正文完
 0