Stack Permutations (original) (raw)

Last Updated : 6 Feb, 2026

We have an empty stack and can perform push and pop operations. We are given two arrays, **a[] and **b[] of same length, where a[] represents the order in which elements are pushed onto the stack, and b[] represents the order in which elements are popped from the stack. Find whether the given push and pop sequences are valid.

**Examples:

**Input: a[] = [1, 2, 3], b[] = [2, 1, 3]
**Output: true
**Explanation: Push 1 and 2. Since b[] requires 2 first, pop 2, then pop 1 next. Finally, push 3 and pop it. The push and pop sequence matches a[] and b[].

**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 Yourselfredirect icon

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.

We push elements from a[] in order, and for each element, we check if it matches the front of b[] (the expected pop order). If it matches, we remove it from b[]; if not, we push it onto a stack. After each push, we also check the top of the stack if it matches the front of b[], we pop from the stack and remove it from b[]. By repeating this, we see if all elements in b[] can be matched. If yes, the pop sequence is valid; otherwise, it is not.

C++ `

#include #include #include #include using namespace std;

bool checkPerm(vector& a, vector& b) { queue 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 a = {1, 2, 3}; vector b = {3, 2, 1};

if (checkPerm(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 checkPerm(int[] a, int[] b) { Queue 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 (checkPerm(a, b))
        System.out.println("true");
    else
        System.out.println("false");
}

}

Python

from collections import deque

def checkPerm(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 checkPerm(a, b):
    print('true')
else:
    print('false')

C#

using System; using System.Collections.Generic;

public class GfG { static bool checkPerm(int[] a, int[] b) { Queue q1 = new Queue(a); Queue q2 = new Queue(b); Stack st = new Stack();

    // 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 (checkPerm(a, b))
        Console.WriteLine("true");
    else
        Console.WriteLine("false");
}

}

JavaScript

function checkPerm(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(checkPerm(a, b));

`

[Expected Approach] Simulating Push and Pop - O(n) time and O(n) space

In this approach, we don’t actually build queues or modify the input arrays. Instead, we directly simulate the push and pop operations on a stack.

Each element from a[] is pushed onto the stack one by one. After every push, we check whether the top of the stack matches the current element of b[]. If it does, we pop it from the stack and move forward in b[]. This process repeats until all elements of a[] have been pushed and checked. If by the end all elements of b[] have been successfully matched and popped, the permutation is valid (returns true); otherwise, it is invalid (returns false).

C++ `

#include #include #include using namespace std;

bool checkPerm(vector& a, vector& b) { stack 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 a = {1, 2, 3}; vector b = {2, 1, 3};

cout << (checkPerm(a, b) ? "true" : "false") << endl;

return 0;

}

Java

import java.util.Stack;

public class GfG { static boolean checkPerm(int[] a, int[] b) { Stack 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(checkPerm(a, b) ? "true" : "false");
}

}

Python

def checkPerm(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 checkPerm(a, b) else "false")

C#

using System; using System.Collections.Generic;

class GfG { static bool checkPerm(int[] a, int[] b) { Stack stack = new Stack(); 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(checkPerm(a, b) ? "true" : "false");
}

}

JavaScript

function checkPerm(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(checkPerm(a, b) ? 'true' : 'false');

`