Stack Permutations

Last Updated : 29 Jul, 2026

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.

Try It Yourself
redirect icon

[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.
C++
#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;
}
Java
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");
    }
}
Python
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')
C#
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");
    }
}
JavaScript
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.
C++
#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;
}
Java
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");
    }
}
Python
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")
C#
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");
    }
}
JavaScript
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
Comment