class Solution:
def validateStackSequences(self, pushed, popped):
stack = []
j = 0
for x in pushed:
stack.append(x)
while stack and j < len(popped) and stack[-1] == popped[j]:
stack.pop()
j += 1
return j == len(popped)
class Solution {
public:
bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
stack<int> st;
int j = 0;
for (int x : pushed) {
st.push(x);
while (!st.empty() && j < popped.size() && st.top() == popped[j]) {
st.pop();
j++;
}
}
return j == popped.size();
}
};
class Solution {
public boolean validateStackSequences(int[] pushed, int[] popped) {
Stack<Integer> stack = new Stack<>();
int j = 0;
for (int x : pushed) {
stack.push(x);
while (!stack.isEmpty() && j < popped.length && stack.peek() == popped[j]) {
stack.pop();
j++;
}
}
return j == popped.length;
}
}
var validateStackSequences = function(pushed, popped) {
let stack = [];
let j = 0;
for (let x of pushed) {
stack.push(x);
while (stack.length > 0 && j < popped.length && stack[stack.length - 1] === popped[j]) {
stack.pop();
j++;
}
}
return j === popped.length;
};
Given two integer arrays pushed and popped of the same length, you must determine if this popped sequence could have been the result of a sequence of stack operations (push and pop) performed on an initially empty stack, where the push operations are done in the order of pushed and each element is pushed exactly once. Each element must be popped exactly once and cannot be reused. There is only one valid stack sequence for each pushed array, and you cannot rearrange the push order.
pushed and popped is unique.pushed or pop from the top of the stack.true if popped is a valid pop sequence for pushed; otherwise, return false.
At first, you might think about simulating every possible sequence of stack operations to see if popped can be generated from pushed. However, this brute-force approach is inefficient and unnecessary. Instead, it's better to simulate the stack process directly, pushing elements as in pushed and popping when the top of the stack matches the next element in popped.
The key insight is to use a stack to mimic the process: push elements from pushed one by one, and whenever the top of the stack matches the next element in popped, pop it. If we can pop all elements in popped this way, the sequence is valid.
j to track the position in popped.x in pushed:
x onto the stack.popped[j]:
j.j equals the length of popped, return true; otherwise, return false.This approach efficiently simulates the stack operations and checks validity in a single pass through the arrays.
Consider pushed = [1,2,3,4,5] and popped = [4,5,3,2,1].
stack = [1]), top != 4.stack = [1,2]), top != 4.stack = [1,2,3]), top != 4.stack = [1,2,3,4]), top == 4, pop (stack = [1,2,3], j = 1).stack = [1,2,3,5]), top == 5, pop (stack = [1,2,3], j = 2).stack = [1,2], j = 3).stack = [1], j = 4).stack = [], j = 5).
All elements in popped are matched and the stack is empty, so the sequence is valid.
O(N), where N is the length of the input arrays. Each element is pushed and popped at most once.O(N) for the stack, since in the worst case all elements could be on the stack at once.
This problem is elegantly solved by simulating stack operations with a single stack and two pointers. By pushing elements from pushed and popping whenever possible to match popped, we efficiently determine if the pop sequence is valid. The solution is both simple and efficient, requiring only linear time and space, and directly models the behavior of a real stack.