Java&C++题解与拓展——leetcode946.验证栈序列【么的新知识】

71 阅读2分钟
每日一题做题记录,参考官方和三叶的题解

题目要求

image.png

思路一:双指针

  • 两个指针分别指向当前应推入or弹出的元素,不断更新栈顶,检查遍历完两个序列时栈顶的位置。
  • 此处直接把pushed数组当成栈用了,若有要求可以重新定义一个数组用【即思路二】。

Java

class Solution {
    public boolean validateStackSequences(int[] pushed, int[] popped) {
        int idx = 0; // 栈顶
        for (int i = 0, j = 0; i < pushed.length; i++) { // 更新栈顶
            pushed[idx++] = pushed[i]; // 模拟push
            while (idx > 0 && pushed[idx - 1] == popped[j] && ++j >= 0)
                idx--; // 模拟pop
        }
        return idx == 0;
    }
}
  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(1)O(1)

C++

class Solution {
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
        int idx = 0; // 栈顶
        for (int i = 0, j = 0; i < pushed.size(); i++) { // 更新栈顶
            pushed[idx++] = pushed[i]; // 模拟push
            while (idx > 0 && pushed[idx - 1] == popped[j] && ++j >= 0)
                idx--; // 模拟pop
        }
        return idx == 0;
    }
};
  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(1)O(1)

Rust

  • 要把题目函数里的pushed变成变量。
impl Solution {
    pub fn validate_stack_sequences(mut pushed: Vec<i32>, popped: Vec<i32>) -> bool {
        let mut idx = 0; // 栈顶
        let mut j = 0;
        for i in 0..pushed.len() {
            pushed[idx] = pushed[i]; //  模拟push
            idx += 1;
            while idx > 0 && pushed[idx - 1] == popped[j] {
                idx -= 1; // 模拟pop
                j += 1;
            }
        }
        idx == 0
    }
}
  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(1)O(1)

思路二:栈模拟

  • 定义一个栈,按照给出的序列模拟一遍,检查栈是否空即可。

Java

class Solution {
    public boolean validateStackSequences(int[] pushed, int[] popped) {
        Deque<Integer> sta = new ArrayDeque<>();
        for (int i =0, j = 0; i < pushed.length; i++) {
            sta.addLast(pushed[i]); // 模拟push
            while(!sta.isEmpty() && sta.peekLast() == popped[j] && ++j >= 0)
                sta.pollLast(); // 模拟pop
        }
        return sta.isEmpty();
    }
}
  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(n)O(n)

C++

class Solution {
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
        stack<int> sta;
        for (int i = 0, j = 0; i < pushed.size(); i++) { // 更新栈顶
            sta.emplace(pushed[i]); // 模拟push
            while (!sta.empty() && sta.top() == popped[j] && ++j >= 0)
                sta.pop(); // 模拟pop
        }
        return sta.empty();
    }
};
  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(n)O(n)

Rust

  • for循环也可以用for_each,反正遍历一遍pushedpushed就结束。
impl Solution {
    pub fn validate_stack_sequences(mut pushed: Vec<i32>, popped: Vec<i32>) -> bool {
        let mut sta = vec![];
        let mut j = 0;
        for i in 0..pushed.len() {
            sta.push(pushed[i]); // 模拟push
            while let Some(&top) = sta.last() {
                if top != popped[j] {
                    break;
                }
                sta.pop(); // 模拟pop
                j += 1;
            }
        }
        sta.is_empty()
    }
}
  • 时间复杂度:O(n)O(n)
  • 空间复杂度:O(n)O(n)

总结

是我最爱的双指针!一个很简单的数据结构应用题,回想起了刚学栈的青涩时光~


欢迎指正与讨论!