You have an empty stack and can perform push and pop operations in it. Given two arrays a[] and b[] of unique elements and both having the same length.
- a[] represents the order in which elements are pushed into a stack.
- b[] represents the order in which elements are expected to be popped from the stack.
Determine whether the given push and pop sequences are valid.
Note: The stack is empty initially and must also be empty after performing all the operations.
Examples:
Input: a[] = [1, 2, 3], b[] = [2, 1, 3]
Output: true
Explanation:
Take 1 from a and push it into the stack,
Take 2 from a and push it into the stack,
Take 2 from b and pop it from the stack,
Take 1 from b and pop it from the stack,
Take 3 from a and push it into the stack,
Take 3 from b and pop it from the stack
So, all the push and pop sequences are valid.Input: a[] = [1, 2, 3], b[] = [3, 1, 2]
Output: false
Explanation: After pushing 1, 2, and 3, we can pop 3 as required. But the next element in b[] is 1, while the stack top is 2. Since 1 is blocked under 2, this order cannot be achieved.
Table of Content
[Naive Approach] Using Queue - O(n) time and O(n) space
The idea is to simulate the stack operations while keeping track of the remaining elements to process using queues.
Working of Approach:
- Traverse the input sequence one by one.
- Push unmatched elements into the stack.
- Remove matching elements from the output sequence.
- Pop from the stack while its top matches the next output element.
- If all output elements are processed, return true; otherwise, return false.
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
using namespace std;
bool validateOp(vector<int>& a, vector<int>& b) {
queue<int> q1;
for (int i = 0; i < a.size(); i++)
q1.push(a[i]);
queue<int> q2;
for (int i = 0; i < b.size(); i++)
q2.push(b[i]);
stack<int> st;
// Dequeue all items one by one
while (!q1.empty()) {
int ele = q1.front();
q1.pop();
if (ele == q2.front()) {
// If matches, dequeue from output queue
q2.pop();
// Pop from stack while top matches q2 front
while (!st.empty() && !q2.empty() && st.top() == q2.front()) {
st.pop();
q2.pop();
}
}
else {
st.push(ele);
}
}
return q2.empty();
}
int main() {
vector<int> a = {1, 2, 3};
vector<int> b = {3, 2, 1};
if (validateOp(a, b))
cout << "true" << endl;
else
cout << "false" << endl;
return 0;
}
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
public class GFG {
static boolean validateOp(int[] a, int[] b) {
Queue<Integer> q1 = new LinkedList<>();
for (int i = 0; i < a.length; i++)
q1.add(a[i]);
Queue<Integer> q2 = new LinkedList<>();
for (int i = 0; i < b.length; i++)
q2.add(b[i]);
Stack<Integer> st = new Stack<>();
// Dequeue all items one by one
while (!q1.isEmpty()) {
int ele = q1.poll();
if (ele == q2.peek()) {
// If matches, dequeue from output queue
q2.poll();
// Pop from stack while top matches q2 front
while (!st.isEmpty() && !q2.isEmpty() && st.peek() == q2.peek()) {
st.pop();
q2.poll();
}
}
else {
st.push(ele);
}
}
return q2.isEmpty();
}
public static void main(String[] args) {
int[] a = {1, 2, 3};
int[] b = {3, 2, 1};
if (validateOp(a, b))
System.out.println("true");
else
System.out.println("false");
}
}
from collections import deque
def validateOp(a, b):
q1 = deque(a)
q2 = deque(b)
st = []
# Dequeue all items one by one
while q1:
ele = q1.popleft()
if ele == q2[0]:
# If matches, dequeue from output queue
q2.popleft()
# Pop from stack while top matches q2 front
while st and q2 and st[-1] == q2[0]:
st.pop()
q2.popleft()
else:
st.append(ele)
return not q2
if __name__ == '__main__':
a = [1, 2, 3]
b = [3, 2, 1]
if validateOp(a, b):
print('true')
else:
print('false')
using System;
using System.Collections.Generic;
public class GFG {
static bool validateOp(int[] a, int[] b) {
Queue<int> q1 = new Queue<int>(a);
Queue<int> q2 = new Queue<int>(b);
Stack<int> st = new Stack<int>();
// Dequeue all items one by one
while (q1.Count > 0) {
int ele = q1.Dequeue();
if (ele == q2.Peek()) {
// If matches, dequeue from output queue
q2.Dequeue();
// Pop from stack while top matches q2 front
while (st.Count > 0 && q2.Count > 0 && st.Peek() == q2.Peek())
{
st.Pop();
q2.Dequeue();
}
}
else
{
st.Push(ele);
}
}
return q2.Count == 0;
}
public static void Main() {
int[] a = { 1, 2, 3 };
int[] b = { 3, 2, 1 };
if (validateOp(a, b))
Console.WriteLine("true");
else
Console.WriteLine("false");
}
}
function validateOp(a, b) {
// simulate queue with array
let q1 = a;
// simulate queue with array
let q2 = b;
let st = [];
// pointer for front of q1
let front1 = 0;
// pointer for front of q2
let front2 = 0;
while (front1 < q1.length) {
let ele = q1[front1];
front1++;
if (ele === q2[front2]) {
front2++;
// Pop from stack while top matches q2 front
while (st.length > 0 && st[st.length - 1] === q2[front2]) {
st.pop();
front2++;
}
} else {
st.push(ele);
}
}
return front2 === q2.length;
}
// Driver Code
let a = [1, 2, 3];
let b = [3, 2, 1];
console.log(validateOp(a, b));
Output
true
[Expected Approach] Simulating Push and Pop - O(n) time and O(n) space
The idea is to simulate the stack directly. Push each input element into the stack and keep popping while the stack top matches the next element in the output sequence. If all output elements are matched, the permutation is valid.
Working of Approach:
- Traverse the input sequence.
- Push each element into the stack.
- Pop elements while the stack top matches the next output element.
- Move to the next output element after every pop.
- If all output elements are matched, return true; otherwise, return false.
Let us understand with an example:
Input: a[] = [1, 2, 3], b[] = [2, 1, 3]
- Push 1 into the stack. Since the top is not 2, do not pop.
- Push 2 into the stack. The top matches 2, so pop it. Now the top is 1, which matches the next output element, so pop it as well.
- Push 3 into the stack. The top matches 3, so pop it.
- All elements in b[] are matched successfully, and the stack becomes empty.
- Hence, the given push and pop sequences are valid, so the answer is true.
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
bool validateOp(vector<int>& a, vector<int>& b) {
stack<int> st;
int j = 0;
for (int i = 0; i < a.size(); i++) {
// Push top of a[] to stack
st.push(a[i]);
// Keep popping from stack while it
// matches front of the output queue
while (!st.empty() && st.top() == b[j]) {
st.pop();
j++;
}
}
return (j == b.size());
}
int main() {
vector<int> a = {1, 2, 3};
vector<int> b = {2, 1, 3};
cout << (validateOp(a, b) ? "true" : "false") << endl;
return 0;
}
import java.util.Stack;
public class GFG {
static boolean validateOp(int[] a, int[] b) {
Stack<Integer> st = new Stack<>();
int j = 0;
for (int i = 0; i < a.length; i++) {
// Push top of a[] to stack
st.push(a[i]);
// Keep popping from stack while it
// matches front of the output array
while (!st.isEmpty() && st.peek().equals(b[j])) {
st.pop();
j++;
}
}
return (j == b.length);
}
public static void main(String[] args) {
int[] a = {1, 2, 3};
int[] b = {2, 1, 3};
System.out.println(validateOp(a, b) ? "true" : "false");
}
}
def validateOp(a, b):
st = []
j = 0
for i in range(len(a)):
# Push top of a[] to stack
st.append(a[i])
# Keep popping from stack while it
# matches front of the output queue
while st and st[-1] == b[j]:
st.pop()
j += 1
return j == len(b)
if __name__ == '__main__':
a = [1, 2, 3]
b = [2, 1, 3]
print("true" if validateOp(a, b) else "false")
using System;
using System.Collections.Generic;
class GFG {
static bool validateOp(int[] a, int[] b) {
Stack<int> stack = new Stack<int>();
int j = 0;
for (int i = 0; i < a.Length; i++) {
// Push top of a[] to stack
stack.Push(a[i]);
// Keep popping from stack while it matches b[j]
while (stack.Count > 0 && stack.Peek() == b[j]) {
stack.Pop();
j++;
}
}
return j == b.Length;
}
static void Main() {
int[] a = { 1, 2, 3 };
int[] b = { 2, 1, 3 };
Console.WriteLine(validateOp(a, b) ? "true" : "false");
}
}
function validateOp(a, b) {
const stack = [];
let j = 0;
for (let i = 0; i < a.length; i++) {
// Push top of a[] to stack
stack.push(a[i]);
// Keep popping from stack while it
// matches front of the output queue
while (stack.length > 0 && stack[stack.length - 1] === b[j]) {
stack.pop();
j++;
}
}
return j === b.length;
}
//Driven Code
const a = [1, 2, 3];
const b = [2, 1, 3];
console.log(validateOp(a, b) ? 'true' : 'false');
Output
true