• 【946. 验证栈序列】


    来源:力扣(LeetCode)

    描述:

    给定 pushedpopped 两个序列,每个序列中的 值都不重复,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时,返回 true;否则,返回 false

    示例 1:

    输入:pushed = [1,2,3,4,5], popped = [4,5,3,2,1]
    输出:true
    解释:我们可以按以下顺序执行:
    push(1), push(2), push(3), push(4), pop() -> 4,
    push(5), pop() -> 5, pop() -> 3, pop() -> 2, pop() -> 1
    
    • 1
    • 2
    • 3
    • 4
    • 5

    示例 2:

    输入:pushed = [1,2,3,4,5], popped = [4,3,5,1,2]
    输出:false
    解释:1 不能在 2 之前弹出。
    
    • 1
    • 2
    • 3

    提示:

    • 1 <= pushed.length <= 1000
    • 0 <= pushed[i] <= 1000
    • pushed 的所有元素 互不相同
    • popped.length == pushed.length
    • popped 是 pushed 的一个排列

    方法:栈模拟

    这道题需要利用给定的两个数组 pushed 和 popped 的如下性质:

    • 数组 pushed 中的元素互不相同;

    • 数组 popped 和数组 pushed 的长度相同;

    • 数组 popped 是数组 pushed 的一个排列。

    根据上述性质,可以得到如下结论:

    • 栈内不可能出现重复元素;

    • 如果 pushed 和 popped 是有效的栈操作序列,则经过所有的入栈和出栈操作之后,每个元素各入栈和出栈一次,栈为空。

    因此,可以遍历两个数组,模拟入栈和出栈操作,判断两个数组是否为有效的栈操作序列。

    模拟入栈操作可以通过遍历数组 pushed 实现。由于只有栈顶的元素可以出栈,因此模拟出栈操作需要判断栈顶元素是否与 popped 的当前元素相同,如果相同则将栈顶元素出栈。由于元素互不相同,因此当栈顶元素与 popped 的当前元素相同时必须将栈顶元素出栈,否则出栈顺序一定不等于 popped。

    根据上述分析,验证栈序列的模拟做法如下:

    1. 遍历数组 pushed,将 pushed 的每个元素依次入栈;

    2. 每次将 pushed 的元素入栈之后,如果栈不为空且栈顶元素与 popped 的当前元素相同,则将栈顶元素出栈,同时遍历数组 popped,直到栈为空或栈顶元素与 popped 的当前元素不同。

    遍历数组 pushed 结束之后,每个元素都按照数组 pushed 的顺序入栈一次。如果栈为空,则每个元素都按照数组 popped 的顺序出栈,返回 true。如果栈不为空,则元素不能按照数组 popped 的顺序出栈,返回 false。

    代码:

    class Solution {
    public:
        bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
            stack<int> st;
            int n = pushed.size();
            for (int i = 0, j = 0; i < n; i++) {
                st.emplace(pushed[i]);
                while (!st.empty() && st.top() == popped[j]) {
                    st.pop();
                    j++;
                }
            }
            return st.empty();
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    执行用时:4 ms, 在所有 C++ 提交中击败了95.94%的用户
    内存消耗:15 MB, 在所有 C++ 提交中击败了16.99%的用户
    复杂度分析
    时间复杂度: O(n),其中 n 是数组 pushed 和 popped 的长度。需要遍历数组 pushed 和 popped 各一次,判断两个数组是否为有效的栈操作序列。
    空间复杂度: O(n),其中 n 是数组 pushed 和 popped 的长度。空间复杂度主要取决于栈空间,栈内元素个数不超过 n。
    author:LeetCode-Solution

  • 相关阅读:
    UVM RAL模型和内置seq
    JavaScript:实现使用 2 个堆栈形成队列算法(附完整源码)
    Selenium 高级定位 Xpath
    安全性归约
    牛客错题笔记
    [北大集训2021]经典游戏
    React Context源码是怎么实现的呢
    装饰器模式
    Linux防火墙常用操作及端口开放
    如何创建与引擎独立的Iceberg表
  • 原文地址:https://blog.csdn.net/Sugar_wolf/article/details/126617872