Open In App

Stack Permutations (Check if an array is stack permutation of other)

Improve
Improve
Like Article
Like
Save
Share
Report

A stack permutation is a permutation of objects in the given input queue which is done by transferring elements from the input queue to the output queue with the help of a stack and the built-in push and pop functions.

The rules are: 

  • Only dequeue from the input queue.
  • Use inbuilt push, and pop functions in the single stack.
  • Stack and input queue must be empty at the end.
  • Only enqueue to the output queue.

There are a huge number of permutations possible using a stack for a single input queue. 
Given two arrays, both of unique elements. One represents the input queue and the other represents the output queue. Our task is to check if the given output is possible through stack permutation.

Examples: 

Input: arr1[] = [ 1, 2, 3 ] , arr2[] = [ 2, 1, 3 ]
Output: YES
Explanation: 
push 1 from input to stack
push 2 from input to stack
pop 2 from stack to output
pop 1 from stack to output
push 3 from input to stack
pop 3 from stack to output

Input: arr1[] = [ 1, 2, 3 ] , arr2[] = [ 3, 1, 2 ]
Output: Not Possible

Recommended Practice

Stack Permutation Using Stack

The idea is to try to convert the input queue to the output queue using a stack, if we are able to do so then the queue is permutable otherwise not. 

Follow the steps mentioned below to implement the approach:

  • Continuously pop elements from the input queue and check if it is equal to the top of output queue or not, if it is not equal to the top of output queue then we will push the element to stack. 
  • Once we find an element in input queue such the top of input queue is equal to top of output queue, we will pop a single element from both input and output queues, and compare the top of stack and top of output queue now. If top of both stack and output queue are equal then pop element from both stack and output queue. If not equal, go to step 1.
  • Repeat above two steps until the input queue becomes empty. At the end if both of the input queue and stack are empty then the input queue is permutable otherwise not. 

Below is the implementation of the above approach:

C++




// Given two arrays, check if one array is
// stack permutation of other.
#include<bits/stdc++.h>
using namespace std;
 
// function to check if input queue is
// permutable to output queue
bool checkStackPermutation(int ip[], int op[], int n)
{
    // Input queue
    queue<int> input;
    for (int i=0;i<n;i++)
        input.push(ip[i]);
 
    // output queue
    queue<int> output;
    for (int i=0;i<n;i++)
        output.push(op[i]);
 
    // stack to be used for permutation
    stack <int> tempStack;
    while (!input.empty())
    {
        int ele = input.front();
        input.pop();
        if (ele == output.front())
        {
            output.pop();
            while (!tempStack.empty())
            {
                if (tempStack.top() == output.front())
                {
                    tempStack.pop();
                    output.pop();
                }
                else
                    break;
            }
        }
        else
            tempStack.push(ele);
    }
 
    // If after processing, both input queue and
    // stack are empty then the input queue is
    // permutable otherwise not.
    return (input.empty()&&tempStack.empty());
}
 
// Driver program to test above function
int main()
{
    // Input Queue
    int input[] = {1, 2, 3};
 
    // Output Queue
    int output[] = {2, 1, 3};
 
    int n = 3;
 
    if (checkStackPermutation(input, output, n))
        cout << "Yes";
    else
        cout << "Not Possible";
    return 0;
}


Java




// Given two arrays, check if one array is
// stack permutation of other.
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
 
class Gfg
{
    // function to check if input queue is
    // permutable to output queue
    static boolean checkStackPermutation(int ip[],
                                    int op[], int n)
    {
        Queue<Integer> input = new LinkedList<>();
 
        // Input queue
        for (int i = 0; i < n; i++)
        {
            input.add(ip[i]);
        }
 
        // Output queue
        Queue<Integer> output = new LinkedList<>();
        for (int i = 0; i < n; i++)
        {
            output.add(op[i]);
        }
 
        // stack to be used for permutation
        Stack<Integer> tempStack = new Stack<>();
        while (!input.isEmpty())
        {
            int ele = input.poll();
 
            if (ele == output.peek())
            {
                output.poll();
                while (!tempStack.isEmpty())
                {
                    if (tempStack.peek() == output.peek())
                    {
                        tempStack.pop();
                        output.poll();
                    }
                    else
                        break;
                }
            }
            else
            {
                tempStack.push(ele);
            }
        }
 
        // If after processing, both input queue and
        // stack are empty then the input queue is
        // permutable otherwise not.
        return (input.isEmpty() && tempStack.isEmpty());
    }
 
    // Driver code
    public static void main(String[] args)
    {
        // Input Queue
        int input[] = { 1, 2, 3 };
 
        // Output Queue
        int output[] = { 2, 1, 3 };
        int n = 3;
        if (checkStackPermutation(input, output, n))
            System.out.println("Yes");
        else
            System.out.println("Not Possible");
    }
}
 
// This code is contributed by Vivekkumar Singh


Python3




# Given two arrays, check if one array is
# stack permutation of other.
from queue import Queue
 
# function to check if Input queue
# is permutable to output queue
def checkStackPermutation(ip, op, n):
     
    # Input queue
    Input = Queue()
    for i in range(n):
        Input.put(ip[i])
 
    # output queue
    output = Queue()
    for i in range(n):
        output.put(op[i])
 
    # stack to be used for permutation
    tempStack = []
    while (not Input.empty()):
        ele = Input.queue[0]
        Input.get()
        if (ele == output.queue[0]):
            output.get()
            while (len(tempStack) != 0):
                if (tempStack[-1] == output.queue[0]):
                    tempStack.pop()
                    output.get()
                else:
                    break
        else:
            tempStack.append(ele)
 
    # If after processing, both Input
    # queue and stack are empty then 
    # the Input queue is permutable
    # otherwise not.
    return (Input.empty() and
        len(tempStack) == 0)
 
# Driver Code
if __name__ == '__main__':
 
    # Input Queue
    Input = [1, 2, 3]
 
    # Output Queue
    output = [2, 1, 3]
 
    n = 3
 
    if (checkStackPermutation(Input,
                              output, n)):
        print("Yes")
    else:
        print("Not Possible")
 
# This code is contributed by PranchalK


C#




// Given two arrays, check if one array is
// stack permutation of other.
using System;
using System.Collections.Generic;
 
class GFG
{
    // function to check if input queue is
    // permutable to output queue
    static bool checkStackPermutation(int []ip,
                                      int []op, int n)
    {
        Queue<int> input = new Queue<int>();
 
        // Input queue
        for (int i = 0; i < n; i++)
        {
            input.Enqueue(ip[i]);
        }
 
        // Output queue
        Queue<int> output = new Queue<int>();
        for (int i = 0; i < n; i++)
        {
            output.Enqueue(op[i]);
        }
 
        // stack to be used for permutation
        Stack<int> tempStack = new Stack<int>();
        while (input.Count != 0)
        {
            int ele = input.Dequeue();
 
            if (ele == output.Peek())
            {
                output.Dequeue();
                while (tempStack.Count != 0)
                {
                    if (tempStack.Peek() == output.Peek())
                    {
                        tempStack.Pop();
                        output.Dequeue();
                    }
                    else
                        break;
                }
            }
            else
            {
                tempStack.Push(ele);
            }
        }
 
        // If after processing, both input queue and
        // stack are empty then the input queue is
        // permutable otherwise not.
        return (input.Count == 0 && tempStack.Count == 0);
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        // Input Queue
        int []input = { 1, 2, 3 };
 
        // Output Queue
        int []output = { 2, 1, 3 };
        int n = 3;
        if (checkStackPermutation(input, output, n))
            Console.WriteLine("Yes");
        else
            Console.WriteLine("Not Possible");
    }
}
 
// This code is contributed by PrinciRaj1992


Javascript




<script>
    // Given two arrays, check if one array is
    // stack permutation of other.
     
    // function to check if input queue is
    // permutable to output queue
    function checkStackPermutation(ip, op, n)
    {
        let input = [];
   
        // Input queue
        for (let i = 0; i < n; i++)
        {
            input.push(ip[i]);
        }
   
        // Output queue
        let output = [];
        for (let i = 0; i < n; i++)
        {
            output.push(op[i]);
        }
   
        // stack to be used for permutation
        let tempStack = [];
        while (input.length != 0)
        {
            let ele = input.shift();
   
            if (ele == output[0])
            {
                output.shift();
                while (tempStack.length != 0)
                {
                    if (tempStack[tempStack.length - 1] == output[0])
                    {
                        tempStack.pop();
                        output.shift();
                    }
                    else
                        break;
                }
            }
            else
            {
                tempStack.push(ele);
            }
        }
   
        // If after processing, both input queue and
        // stack are empty then the input queue is
        // permutable otherwise not.
        return (input.length == 0 && tempStack.length == 0);
    }
     
    // Input Queue
    let input = [ 1, 2, 3 ];
 
    // Output Queue
    let output = [ 2, 1, 3 ];
    let n = 3;
    if (checkStackPermutation(input, output, n))
      document.write("Yes");
    else
      document.write("Not Possible");
     
    // This code is contributed by rameshtravel07.
</script>


Output

Yes

Time Complexity: O(N)
Auxiliary Space: O(N)

Optimized Approach

The idea to start iterating on the input array and storing its element one by one in a stack and if the top of our stack matches with an element in the output array we will pop that element from the stack and compare the next element of the output array with the top of our stack if again it matches then again pop until our stack isn’t empty 

Below is the implementation of the above approach:

C++




// Given two arrays, check if one array is
// stack permutation of other.
#include<bits/stdc++.h>
using namespace std;
 
// function to check if input array is
// permutable to output array
bool checkStackPermutation(int ip[], int op[], int n)
{
     // we will be pushing elements from input array to stack uptill top of our stack
     //  matches with first element of output array
      stack<int>s;
      
    // will maintain a variable j to iterate on output array
      int j=0;
   
    // will iterate one by one in input array
      for(int i=0;i<n;i++)
      {
        // pushed an element from input array to stack
        s.push(ip[i]);
        // if our stack isn't empty and top matches with output array
        // then we will keep popping out from stack uptill top matches with
        // output array
        while(!s.empty() and s.top()==op[j])
        {
          s.pop();
          // increasing j so next time we can compare next element in output array
          j++;
        }
      }
       
      // if output array was a correct permutation of input array then
      // by now our stack should be empty
      if(s.empty())
      {
        return true;
      }
      return false
       
}
 
// Driver program to test above function
int main()
{
    // Input Array
    int input[] = {4,5,6,7,8};
 
    // Output Array
    int output[] = {8,7,6,5,4};
 
    int n = 5;
 
    if (checkStackPermutation(input, output, n))
        cout << "Yes";
    else
        cout << "Not Possible";
    return 0;
}


Java




// Java program to check if one array is
// stack permutation of other.
 
import java.util.Stack;
class Rextester {
    // function to check if input array is
    // permutable to output array
    static Boolean checkStackPermutation(int ip[], int op[],
                                         int n)
    {
        // we will be pushing elements from input array to
        // stack uptill top of our stack matches with first
        // element of output array
        Stack<Integer> s = new Stack<Integer>();
 
        // will maintain a variable j to iterate on output
        // array
        int j = 0;
 
        // will iterate one by one in input array
        for (int i = 0; i < n; i++) {
            // pushed an element from input array to stack
            s.push(ip[i]);
            // if our stack isn't empty and top matches with
            // output array then we will keep popping out
            // from stack uptill top matches with output
            // array
            while (!s.isEmpty() && s.peek() == op[j]) {
                s.pop();
                // increasing j so next time we can compare
                // next element in output array
                j++;
            }
        }
 
        // if output array was a correct permutation of
        // input array then by now our stack should be empty
        if (s.isEmpty()) {
            return true;
        }
        return false;
    }
 
    // Driver program to test above function
    public static void main(String args[])
    {
        // Input Array
        int input[] = { 4, 5, 6, 7, 8 };
 
        // Output Array
        int output[] = { 8, 7, 6, 5, 4 };
 
        int n = 5;
 
        if (checkStackPermutation(input, output, n))
            System.out.println("Yes");
        else
            System.out.println("Not Possible");
    }
}
 
// This code is contributed by Lovely Jain


Python3




# Given two arrays, check if one array is
# stack permutation of other.
 
# function to check if input array is
# permutable to output array
def checkStackPermutation(ip, op, n):
 
    # we will be appending elements from input array to stack uptill top of our stack
    # matches with first element of output array
    s = []
     
    # will maintain a variable j to iterate on output array
    j = 0
 
    # will iterate one by one in input array
    for i in range(n):
 
        # appended an element from input array to stack
        s.append(ip[i])
         
        # if our stack isn't empty and top matches with output array
        # then we will keep popping out from stack uptill top matches with
        # output array
        while(len(s) > 0 and s[- 1] == op[j]):
            s.pop()
             
            # increasing j so next time we can compare next element in output array
            j += 1
         
     
    # if output array was a correct permutation of input array then
    # by now our stack should be empty
    if(len(s)  == 0):
        return True
     
    return False
     
# Driver program to test above function
 
# Input Array
input = [4,5,6,7,8]
 
# Output Array
 
output = [8,7,6,5,4]
n = 5
if (checkStackPermutation(input, output, n)):
    print("Yes")
else:
    print("Not Possible")
 
# This code is contributed by shinjanpatra


C#




// Given two arrays, check if one array is
// stack permutation of other.
using System;
using System.Collections.Generic;
 
class GFG
{
   
  // function to check if input array is
  // permutable to output array
  static bool checkStackPermutation(int[] ip, int[] op,
                                    int n)
  {
     
    // we will be pushing elements from input array to
    // stack uptill top of our stack
    //  matches with first element of output array
    Stack<int> s = new Stack<int>();
 
    // will maintain a variable j to iterate on output
    // array
 
    int j = 0;
 
    // will iterate one by one in input array
    for (int i = 0; i < n; i++) {
      // pushed an element from input array to stack
      s.Push(ip[i]);
      // if our stack isn't empty and top matches with
      // output array then we will keep popping out
      // from stack uptill top matches with output
      // array
      while (s.Count != 0 && s.Peek() == op[j]) {
        // increasing j so next time we can compare
        // next element in output array
        s.Pop();
        j = j + 1;
      }
    }
    // if output array was a correct permutation of
    // input array then by now our stack should be empty
    if (s.Count == 0) {
      return true;
    }
    return false;
  }
 
  public static void Main(String[] args)
  {
    // Input Queue
    int[] input = { 1, 2, 3 };
 
    // Output Queue
    int[] output = { 2, 1, 3 };
    int n = 3;
    if (checkStackPermutation(input, output, n))
      Console.WriteLine("Yes");
    else
      Console.WriteLine("Not Possible");
  }
}
 
// This code is contributed by aadityamaharshi21.


Javascript




<script>
 
// Given two arrays, check if one array is
// stack permutation of other.
 
// function to check if input array is
// permutable to output array
function checkStackPermutation(ip, op, n)
{
    // we will be pushing elements from input array to stack uptill top of our stack
    // matches with first element of output array
    let s = [];
     
    // will maintain a variable j to iterate on output array
    let j = 0;
 
    // will iterate one by one in input array
    for(let i = 0; i < n; i++)
    {
        // pushed an element from input array to stack
        s.push(ip[i]);
         
        // if our stack isn't empty and top matches with output array
        // then we will keep popping out from stack uptill top matches with
        // output array
        while(s.length > 0 && s[s.length - 1] == op[j])
        {
            s.pop();
             
            // increasing j so next time we can compare next element in output array
            j++;
        }
    }
     
    // if output array was a correct permutation of input array then
    // by now our stack should be empty
    if(s.length  == 0)
    {
        return true;
    }
    return false;
     
}
 
// Driver program to test above function
 
// Input Array
let input = [4,5,6,7,8];
 
// Output Array
 
let output = [8,7,6,5,4];
 
let n = 5;
 
if (checkStackPermutation(input, output, n))
    document.write("Yes");
else
    document.write("Not Possible");
 
// This code is contributed by shinjanpatra
 
</script>


Output

Yes

Time Complexity: O(N)
Auxiliary Space: O(N)

Optimize Approach 2:

The above code already has a linear time complexity, but we can make a few small optimizations to make it more efficient:

Use std::vector instead of a fixed-size array. This will make it easier to pass the arrays to the function and avoid potential buffer overflows.

Reserve memory in the vector to avoid unnecessary allocations. We know the exact size of the arrays, so we can reserve that much memory in the vectors to avoid resizing during the push operation.

Avoid unnecessary comparisons by breaking out of the loop early. If we encounter an element in the input array that is already in the output array, we know that it cannot be a valid stack permutation, so we can return false immediately.

Here’s the optimized code:

C++




#include <iostream>
#include <vector>
#include <stack>
 
using namespace std;
 
bool checkStackPermutation(const vector<int>& input, const vector<int>& output) {
    stack<int> s;
    int j = 0;
 
    for (int i = 0; i < input.size(); i++) {
        s.push(input[i]);
 
        while (!s.empty() && s.top() == output[j]) {
            s.pop();
            j++;
        }
}
if(j==output.size())
    return true;
  return false;
}
 
int main() {
    vector<int> input = {4, 5, 6, 7, 8};
    vector<int> output = {8, 7, 6, 5, 4};
 
    if (input.size() != output.size()) {
        cout << "Not Possible" << endl;
        return 0;
    }
 
    checkStackPermutation(input, output) ? cout << "Yes" << endl : cout << "Not Possible" << endl;
 
    return 0;
}


Java




import java.util.*;
 
public class Main {
    public static boolean checkStackPermutation(List<Integer> input, List<Integer> output) {
        Stack<Integer> s = new Stack<>();
        int j = 0;
 
        for (int i = 0; i < input.size(); i++) {
            s.push(input.get(i));
 
            while (!s.empty() && s.peek() == output.get(j)) {
                s.pop();
                j++;
            }
 
            if (j < output.size() && s.peek() == output.get(j)) {
                return false;
            }
        }
 
        return true;
    }
 
    public static void main(String[] args) {
        List<Integer> input = new ArrayList<>(Arrays.asList(4, 5, 6, 7, 8));
        List<Integer> output = new ArrayList<>(Arrays.asList(8, 7, 6, 5, 4));
 
        if (input.size() != output.size()) {
            System.out.println("Not Possible");
            return;
        }
 
        if (checkStackPermutation(input, output)) {
            System.out.println("Yes");
        } else {
            System.out.println("Not Possible");
        }
    }
}


Python3




from typing import List
 
def checkStackPermutation(ip: List[int], op: List[int]) -> bool:
    s = []
    j = 0
 
    for i in range(len(ip)):
        s.append(ip[i])
 
        while s and s[-1] == op[j]:
            s.pop()
            j += 1
 
        if j < len(op) and s[-1] == op[j]:
            return False
 
    return True
 
input_arr = [4, 5, 6, 7, 8]
output_arr = [8, 7, 6, 5, 4]
 
if len(input_arr) != len(output_arr):
    print("Not Possible")
else:
    if checkStackPermutation(input_arr, output_arr):
        print("Yes")
    else:
        print("Not Possible")


C#




using System;
using System.Collections.Generic;
 
public class MainClass {
    public static bool CheckStackPermutation(List<int> input, List<int> output) {
        Stack<int> s = new Stack<int>();
        int j = 0;
 
        for (int i = 0; i < input.Count; i++) {
            s.Push(input[i]);
 
            while (s.Count > 0 && s.Peek() == output[j]) {
                s.Pop();
                j++;
            }
 
            if (j < output.Count && s.Peek() == output[j]) {
                return false;
            }
        }
 
        return true;
    }
 
    public static void Main(string[] args) {
        List<int> input = new List<int>() { 4, 5, 6, 7, 8 };
        List<int> output = new List<int>() { 8, 7, 6, 5, 4 };
 
        if (input.Count != output.Count) {
            Console.WriteLine("Not Possible");
            return;
        }
 
        if (CheckStackPermutation(input, output)) {
            Console.WriteLine("Yes");
        } else {
            Console.WriteLine("Not Possible");
        }
    }
}


Javascript




function checkStackPermutation(ip, op) {
  let s = [];
  let j = 0;
 
  for (let i = 0; i < ip.length; i++) {
    s.push(ip[i]);
 
    while (s.length > 0 && s[s.length - 1] === op[j]) {
      s.pop();
      j++;
    }
 
    if (j < op.length && s[s.length - 1] === op[j]) {
      return false;
    }
  }
 
  return true;
}
 
const inputArr = [4, 5, 6, 7, 8];
const outputArr = [8, 7, 6, 5, 4];
 
if (inputArr.length !== outputArr.length) {
  console.log("Not Possible");
} else {
  if (checkStackPermutation(inputArr, outputArr)) {
    console.log("Yes");
  } else {
    console.log("Not Possible");
  }
}


Output

Yes

Time Complexity: O(N)
Auxiliary Space: O(N)



Last Updated : 11 Jul, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads