Stack Permutations (Check if an array is stack permutation of other)
Last Updated :
11 Jul, 2023
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
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++
#include<bits/stdc++.h>
using namespace std;
bool checkStackPermutation( int ip[], int op[], int n)
{
queue< int > input;
for ( int i=0;i<n;i++)
input.push(ip[i]);
queue< int > output;
for ( int i=0;i<n;i++)
output.push(op[i]);
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);
}
return (input.empty()&&tempStack.empty());
}
int main()
{
int input[] = {1, 2, 3};
int output[] = {2, 1, 3};
int n = 3;
if (checkStackPermutation(input, output, n))
cout << "Yes" ;
else
cout << "Not Possible" ;
return 0;
}
|
Java
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
class Gfg
{
static boolean checkStackPermutation( int ip[],
int op[], int n)
{
Queue<Integer> input = new LinkedList<>();
for ( int i = 0 ; i < n; i++)
{
input.add(ip[i]);
}
Queue<Integer> output = new LinkedList<>();
for ( int i = 0 ; i < n; i++)
{
output.add(op[i]);
}
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);
}
}
return (input.isEmpty() && tempStack.isEmpty());
}
public static void main(String[] args)
{
int input[] = { 1 , 2 , 3 };
int output[] = { 2 , 1 , 3 };
int n = 3 ;
if (checkStackPermutation(input, output, n))
System.out.println( "Yes" );
else
System.out.println( "Not Possible" );
}
}
|
Python3
from queue import Queue
def checkStackPermutation(ip, op, n):
Input = Queue()
for i in range (n):
Input .put(ip[i])
output = Queue()
for i in range (n):
output.put(op[i])
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)
return ( Input .empty() and
len (tempStack) = = 0 )
if __name__ = = '__main__' :
Input = [ 1 , 2 , 3 ]
output = [ 2 , 1 , 3 ]
n = 3
if (checkStackPermutation( Input ,
output, n)):
print ( "Yes" )
else :
print ( "Not Possible" )
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static bool checkStackPermutation( int []ip,
int []op, int n)
{
Queue< int > input = new Queue< int >();
for ( int i = 0; i < n; i++)
{
input.Enqueue(ip[i]);
}
Queue< int > output = new Queue< int >();
for ( int i = 0; i < n; i++)
{
output.Enqueue(op[i]);
}
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);
}
}
return (input.Count == 0 && tempStack.Count == 0);
}
public static void Main(String[] args)
{
int []input = { 1, 2, 3 };
int []output = { 2, 1, 3 };
int n = 3;
if (checkStackPermutation(input, output, n))
Console.WriteLine( "Yes" );
else
Console.WriteLine( "Not Possible" );
}
}
|
Javascript
<script>
function checkStackPermutation(ip, op, n)
{
let input = [];
for (let i = 0; i < n; i++)
{
input.push(ip[i]);
}
let output = [];
for (let i = 0; i < n; i++)
{
output.push(op[i]);
}
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);
}
}
return (input.length == 0 && tempStack.length == 0);
}
let input = [ 1, 2, 3 ];
let output = [ 2, 1, 3 ];
let n = 3;
if (checkStackPermutation(input, output, n))
document.write( "Yes" );
else
document.write( "Not Possible" );
</script>
|
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++
#include<bits/stdc++.h>
using namespace std;
bool checkStackPermutation( int ip[], int op[], int n)
{
stack< int >s;
int j=0;
for ( int i=0;i<n;i++)
{
s.push(ip[i]);
while (!s.empty() and s.top()==op[j])
{
s.pop();
j++;
}
}
if (s.empty())
{
return true ;
}
return false ;
}
int main()
{
int input[] = {4,5,6,7,8};
int output[] = {8,7,6,5,4};
int n = 5;
if (checkStackPermutation(input, output, n))
cout << "Yes" ;
else
cout << "Not Possible" ;
return 0;
}
|
Java
import java.util.Stack;
class Rextester {
static Boolean checkStackPermutation( int ip[], int op[],
int n)
{
Stack<Integer> s = new Stack<Integer>();
int j = 0 ;
for ( int i = 0 ; i < n; i++) {
s.push(ip[i]);
while (!s.isEmpty() && s.peek() == op[j]) {
s.pop();
j++;
}
}
if (s.isEmpty()) {
return true ;
}
return false ;
}
public static void main(String args[])
{
int input[] = { 4 , 5 , 6 , 7 , 8 };
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" );
}
}
|
Python3
def checkStackPermutation(ip, op, n):
s = []
j = 0
for i in range (n):
s.append(ip[i])
while ( len (s) > 0 and s[ - 1 ] = = op[j]):
s.pop()
j + = 1
if ( len (s) = = 0 ):
return True
return False
input = [ 4 , 5 , 6 , 7 , 8 ]
output = [ 8 , 7 , 6 , 5 , 4 ]
n = 5
if (checkStackPermutation( input , output, n)):
print ( "Yes" )
else :
print ( "Not Possible" )
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static bool checkStackPermutation( int [] ip, int [] op,
int n)
{
Stack< int > s = new Stack< int >();
int j = 0;
for ( int i = 0; i < n; i++) {
s.Push(ip[i]);
while (s.Count != 0 && s.Peek() == op[j]) {
s.Pop();
j = j + 1;
}
}
if (s.Count == 0) {
return true ;
}
return false ;
}
public static void Main(String[] args)
{
int [] input = { 1, 2, 3 };
int [] output = { 2, 1, 3 };
int n = 3;
if (checkStackPermutation(input, output, n))
Console.WriteLine( "Yes" );
else
Console.WriteLine( "Not Possible" );
}
}
|
Javascript
<script>
function checkStackPermutation(ip, op, n)
{
let s = [];
let j = 0;
for (let i = 0; i < n; i++)
{
s.push(ip[i]);
while (s.length > 0 && s[s.length - 1] == op[j])
{
s.pop();
j++;
}
}
if (s.length == 0)
{
return true ;
}
return false ;
}
let input = [4,5,6,7,8];
let output = [8,7,6,5,4];
let n = 5;
if (checkStackPermutation(input, output, n))
document.write( "Yes" );
else
document.write( "Not Possible" );
</script>
|
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" );
}
}
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Please Login to comment...