Open In App

Stack Permutations

Last Updated : 15 Sep, 2025
Comments
Improve
Suggest changes
81 Likes
Like
Report

We have an empty stack and can perform push and pop operations. We are given two arrays, a[] and b[], 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.

[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 <iostream>
#include <queue>
#include <stack>
#include <vector>
using namespace std;

bool checkPerm(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 (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<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 (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<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 (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)); 

Output
true

[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 <iostream>
#include <vector>
#include <stack>
using namespace std;

bool checkPerm(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 << (checkPerm(a, b) ? "true" : "false") << endl;

    return 0;
}
Java
import java.util.Stack;

public class GfG {
    static boolean checkPerm(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(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<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(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');

Output
true

Article Tags :

Explore