We have discussed space-efficient implementation of 2 stacks in a single array. In this post, a general solution for k stacks is discussed. Following is the detailed problem statement. Create a data structure kStacks that represents k stacks. Implementation of kStacks should use only one array, i.e., k stacks should use the same array for storing elements.
The following functions must be supported by k Stacks. push(int x, int sn) –> pushes x to stack number ‘sn’ where sn is from 0 to k-1 pop(int sn) –> pops an element from stack number ‘sn’ where sn is from 0 to k-1
Method 1 (Divide the array in slots of size n/k) A simple way to implement k stacks is to divide the array in k slots of size n/k each, and fix the slots for different stacks, i.e., use arr[0] to arr[n/k-1] for first stack, and arr[n/k] to arr[2n/k-1] for stack2 where arr[] is the array to be used to implement two stacks and size of array be n. The problem with this method is inefficient use of array space. A stack push operation may result in stack overflow even if there is space available in arr[]. For example, say the k is 2 and array size (n) is 6 and we push 3 elements to first and do not push anything to second stack. When we push 4th element to first, there will be overflow even if we have space for 3 more elements in array.
Method 2 (A space-efficient implementation) The idea is to use two extra arrays for efficient implementation of k stacks in an array. This may not make much sense for integer stacks, but stack items can be large for example stacks of employees, students, etc where every item is of hundreds of bytes. For such large stacks, the extra space used is comparatively very less as we use two integer arrays as extra space.
Following are the two extra arrays are used:
1) top[]: This is of size k and stores indexes of top elements in all stacks.
2) next[]: This is of size n and stores indexes of next item for the items in array arr[].
Here arr[] is actual array that stores k stacks. Together with k stacks, a stack of free slots in arr[] is also maintained. The top of this stack is stored in a variable ‘free’. All entries in top[] are initialized as -1 to indicate that all stacks are empty. All entries next[i] are initialized as i+1 because all slots are free initially and pointing to next slot. Top of free stack, ‘free’ is initialized as 0.
Algorithm:
- Initialize an array of size k to keep track of the top element of each stack.
- Initialize an array next of size n, where n is the total size of the array that will hold the k stacks. Set the value of next[i] to i+1 for all 0 ≤ i < n-1, and next[n-1] to -1. This array will be used to keep track of the next element in the stack.
- Initialize an array top of size k to store the index of the top element of each stack. Set the value of top[i] to -1 for all 0 ≤ i < k.
- To push an element onto the i-th stack, do the following:
- Check if the array is full by checking if next[0] is -1. If it is, return an error message indicating that the stack is full.
- Set the value of next[0] to top[i].
- Set the value of top[i] to 0.
- Set the value of next[top[i]] to the new element’s index.
- Increment the value of top[i] by the block size.
- To pop an element from the i-th stack, do the following:
- Check if the stack is empty by checking if top[i] is -1. If it is, return an error message indicating that the stack is empty.
- Decrement the value of top[i] by the block size.
- Set the value of next[top[i]] to -1.
- Return the element at the index top[i] + block size – 1.
Following is the implementation of the above idea.
C++
| // A C++ program to demonstrate implementation of k stacks in a single // array in time and space efficient way#include<bits/stdc++.h>usingnamespacestd;// A C++ class to represent k stacks in a single array of size nclasskStacks{    int*arr;   // Array of size n to store actual content to be stored in stacks    int*top;   // Array of size k to store indexes of top elements of stacks    int*next;  // Array of size n to store next entry in all stacks                // and free list    intn, k;    intfree; // To store beginning index of free listpublic:    //constructor to create k stacks in an array of size n    kStacks(intk, intn);    // A utility function to check if there is space available    boolisFull()   {  return(free== -1);  }    // To push an item in stack number 'sn' where sn is from 0 to k-1    voidpush(intitem, intsn);    // To pop an from stack number 'sn' where sn is from 0 to k-1    intpop(intsn);    // To check whether stack number 'sn' is empty or not    boolisEmpty(intsn)  {  return(top[sn] == -1); }};//constructor to create k stacks in an array of size nkStacks::kStacks(intk1, intn1){    // Initialize n and k, and allocate memory for all arrays    k = k1, n = n1;    arr = newint[n];    top = newint[k];    next = newint[n];    // Initialize all stacks as empty    for(inti = 0; i < k; i++)        top[i] = -1;    // Initialize all spaces as free    free= 0;    for(inti=0; i<n-1; i++)        next[i] = i+1;    next[n-1] = -1;  // -1 is used to indicate end of free list}// To push an item in stack number 'sn' where sn is from 0 to k-1voidkStacks::push(intitem, intsn){    // Overflow check    if(isFull())    {        cout << "\nStack Overflow\n";        return;    }    inti = free;      // Store index of first free slot    // Update index of free slot to index of next slot in free list    free= next[i];    // Update next of top and then top for stack number 'sn'    next[i] = top[sn];    top[sn] = i;    // Put the item in array    arr[i] = item;}// To pop an element from stack number 'sn' where sn is from 0 to k-1intkStacks::pop(intsn){    // Underflow check    if(isEmpty(sn))    {         cout << "\nStack Underflow\n";         returnINT_MAX;    }    // Find index of top item in stack number 'sn'    inti = top[sn];    top[sn] = next[i];  // Change top to store next of previous top    // Attach the previous top to the beginning of free list    next[i] = free;    free= i;    // Return the previous top item    returnarr[i];}/* Driver program to test twoStacks class */intmain(){    // Let us create 3 stacks in an array of size 10    intk = 3, n = 10;    kStacks ks(k, n);    // Let us put some items in stack number 2    ks.push(15, 2);    ks.push(45, 2);    // Let us put some items in stack number 1    ks.push(17, 1);    ks.push(49, 1);    ks.push(39, 1);    // Let us put some items in stack number 0    ks.push(11, 0);    ks.push(9, 0);    ks.push(7, 0);    cout << "Popped element from stack 2 is "<< ks.pop(2) << endl;    cout << "Popped element from stack 1 is "<< ks.pop(1) << endl;    cout << "Popped element from stack 0 is "<< ks.pop(0) << endl;    return0;} | 
Java
| // Java program to demonstrate implementation of k stacks in a single // array in time and space efficient waypublicclassGFG {    // A Java class to represent k stacks in a single array of size n    staticclassKStack     {        intarr[];   // Array of size n to store actual content to be stored in stacks        inttop[];   // Array of size k to store indexes of top elements of stacks        intnext[];  // Array of size n to store next entry in all stacks                     // and free list        intn, k;        intfree; // To store beginning index of free list        //constructor to create k stacks in an array of size n        KStack(intk1, intn1)         {            // Initialize n and k, and allocate memory for all arrays            k = k1;            n = n1;            arr = newint[n];            top = newint[k];            next = newint[n];            // Initialize all stacks as empty            for(inti = 0; i < k; i++)                top[i] = -1;            // Initialize all spaces as free            free = 0;            for(inti = 0; i < n - 1; i++)                next[i] = i + 1;            next[n - 1] = -1; // -1 is used to indicate end of free list        }        // A utility function to check if there is space available        booleanisFull()         {            return(free == -1);        }        // To push an item in stack number 'sn' where sn is from 0 to k-1        voidpush(intitem, intsn)         {            // Overflow check            if(isFull())             {                System.out.println("Stack Overflow");                return;            }            inti = free; // Store index of first free slot            // Update index of free slot to index of next slot in free list            free = next[i];            // Update next of top and then top for stack number 'sn'            next[i] = top[sn];            top[sn] = i;            // Put the item in array            arr[i] = item;        }        // To pop an element from stack number 'sn' where sn is from 0 to k-1        intpop(intsn)         {            // Underflow check            if(isEmpty(sn))             {                System.out.println("Stack Underflow");                returnInteger.MAX_VALUE;            }            // Find index of top item in stack number 'sn'            inti = top[sn];            top[sn] = next[i]; // Change top to store next of previous top            // Attach the previous top to the beginning of free list            next[i] = free;            free = i;            // Return the previous top item            returnarr[i];        }        // To check whether stack number 'sn' is empty or not        booleanisEmpty(intsn)         {            return(top[sn] == -1);        }    }    // Driver program    publicstaticvoidmain(String[] args)     {        // Let us create 3 stacks in an array of size 10        intk = 3, n = 10;                KStack ks = newKStack(k, n);        ks.push(15, 2);        ks.push(45, 2);        // Let us put some items in stack number 1        ks.push(17, 1);        ks.push(49, 1);        ks.push(39, 1);        // Let us put some items in stack number 0        ks.push(11, 0);        ks.push(9, 0);        ks.push(7, 0);        System.out.println("Popped element from stack 2 is "+ ks.pop(2));        System.out.println("Popped element from stack 1 is "+ ks.pop(1));        System.out.println("Popped element from stack 0 is "+ ks.pop(0));    }}// This code is Contributed by Sumit Ghosh | 
Python3
| # Python 3 program to demonstrate implementation # of k stacks in a single array in time and space # efficient way classKStacks:        def__init__(self, k, n):        self.k =k # Number of stacks.        self.n =n # Total size of array holding                    # all the 'k' stacks.        # Array which holds 'k' stacks.        self.arr =[0] *self.n        # All stacks are empty to begin with         # (-1 denotes stack is empty).        self.top =[-1] *self.k        # Top of the free stack.        self.free =0        # Points to the next element in either        # 1. One of the 'k' stacks or,        # 2. The 'free' stack.        self.next=[i +1fori inrange(self.n)]        self.next[self.n -1] =-1    # Check whether given stack is empty.    defisEmpty(self, sn):        returnself.top[sn] ==-1    # Check whether there is space left for     # pushing new elements or not.    defisFull(self):        returnself.free ==-1    # Push 'item' onto given stack number 'sn'.    defpush(self, item, sn):        ifself.isFull():            print("Stack Overflow")            return        # Get the first free position         # to insert at.        insert_at =self.free        # Adjust the free position.        self.free =self.next[self.free]        # Insert the item at the free         # position we obtained above.        self.arr[insert_at] =item        # Adjust next to point to the old        # top of stack element.        self.next[insert_at] =self.top[sn]        # Set the new top of the stack.        self.top[sn] =insert_at    # Pop item from given stack number 'sn'.    defpop(self, sn):        ifself.isEmpty(sn):            returnNone        # Get the item at the top of the stack.        top_of_stack =self.top[sn]        # Set new top of stack.        self.top[sn] =self.next[self.top[sn]]        # Push the old top_of_stack to         # the 'free' stack.        self.next[top_of_stack] =self.free        self.free =top_of_stack        returnself.arr[top_of_stack]    defprintstack(self, sn):        top_index =self.top[sn]        while(top_index !=-1):            print(self.arr[top_index])            top_index =self.next[top_index]# Driver Codeif__name__ =="__main__":        # Create 3 stacks using an     # array of size 10.    kstacks =KStacks(3, 10)    # Push some items onto stack number 2.    kstacks.push(15, 2)    kstacks.push(45, 2)    # Push some items onto stack number 1.    kstacks.push(17, 1)    kstacks.push(49, 1)    kstacks.push(39, 1)    # Push some items onto stack number 0.    kstacks.push(11, 0)    kstacks.push(9, 0)    kstacks.push(7, 0)    print("Popped element from stack 2 is "+                         str(kstacks.pop(2)))    print("Popped element from stack 1 is "+                         str(kstacks.pop(1)))    print("Popped element from stack 0 is "+                         str(kstacks.pop(0)))    kstacks.printstack(0)# This code is contributed by Varun Patil | 
C#
| usingSystem;// C# program to demonstrate implementation of k stacks in a single  // array in time and space efficient way publicclassGFG{    // A c# class to represent k stacks in a single array of size n     publicclassKStack    {        publicint[] arr; // Array of size n to store actual content to be stored in stacks        publicint[] top; // Array of size k to store indexes of top elements of stacks        publicint[] next; // Array of size n to store next entry in all stacks                     // and free list         publicintn, k;        publicintfree; // To store beginning index of free list        //constructor to create k stacks in an array of size n         publicKStack(intk1, intn1)        {            // Initialize n and k, and allocate memory for all arrays             k = k1;            n = n1;            arr = newint[n];            top = newint[k];            next = newint[n];            // Initialize all stacks as empty             for(inti = 0; i < k; i++)            {                top[i] = -1;            }            // Initialize all spaces as free             free = 0;            for(inti = 0; i < n - 1; i++)            {                next[i] = i + 1;            }            next[n - 1] = -1; // -1 is used to indicate end of free list        }        // A utility function to check if there is space available         publicvirtualboolFull        {            get            {                return(free == -1);            }        }        // To push an item in stack number 'sn' where sn is from 0 to k-1         publicvirtualvoidpush(intitem, intsn)        {            // Overflow check             if(Full)            {                Console.WriteLine("Stack Overflow");                return;            }            inti = free; // Store index of first free slot            // Update index of free slot to index of next slot in free list             free = next[i];            // Update next of top and then top for stack number 'sn'             next[i] = top[sn];            top[sn] = i;            // Put the item in array             arr[i] = item;        }        // To pop an element from stack number 'sn' where sn is from 0 to k-1         publicvirtualintpop(intsn)        {            // Underflow check             if(isEmpty(sn))            {                Console.WriteLine("Stack Underflow");                returnint.MaxValue;            }            // Find index of top item in stack number 'sn'             inti = top[sn];            top[sn] = next[i]; // Change top to store next of previous top            // Attach the previous top to the beginning of free list             next[i] = free;            free = i;            // Return the previous top item             returnarr[i];        }        // To check whether stack number 'sn' is empty or not         publicvirtualboolisEmpty(intsn)        {            return(top[sn] == -1);        }    }    // Driver program     publicstaticvoidMain(string[] args)    {        // Let us create 3 stacks in an array of size 10         intk = 3, n = 10;        KStack ks = newKStack(k, n);        ks.push(15, 2);        ks.push(45, 2);        // Let us put some items in stack number 1         ks.push(17, 1);        ks.push(49, 1);        ks.push(39, 1);        // Let us put some items in stack number 0         ks.push(11, 0);        ks.push(9, 0);        ks.push(7, 0);        Console.WriteLine("Popped element from stack 2 is "+ ks.pop(2));        Console.WriteLine("Popped element from stack 1 is "+ ks.pop(1));        Console.WriteLine("Popped element from stack 0 is "+ ks.pop(0));    }}// This code is contributed by Shrikant13 | 
Javascript
| <script>// javascript program to demonstrate implementation of k stacks in a single // array in time and space efficient way    // A javascript class to represent k stacks in a single array of size n     class KStack {            // constructor to create k stacks in an array of size n        constructor(k1 , n1)         {                    // Initialize n and k, and allocate memory for all arrays            this.k = k1;            this.n = n1;            this.arr = Array(n).fill(0);            this.top = Array(k).fill(-1);            this.next = Array(n).fill(0);                    // Initialize all spaces as free            this.free = 0;            for(vari = 0; i < n - 1; i++)                this.next[i] = i + 1;            this.next[n - 1] = -1; // -1 is used to indicate end of free list        }        // A utility function to check if there is space available         isFull() {            return(this.free == -1);        }        // To push an item in stack number 'sn' where sn is from 0 to k-1         push(item , sn)         {                     // Overflow check            if(this.isFull()) {                document.write("Stack Overflow");                return;            }            vari = this.free; // Store index of first free slot            // Update index of free slot to index of next slot in free list            this.free = this.next[i];            // Update next of top and then top for stack number 'sn'            this.next[i] = this.top[sn];            this.top[sn] = i;            // Put the item in array            this.arr[i] = item;        }        // To pop an element from stack number 'sn' where sn is from 0 to k-1         pop(sn)         {                     // Underflow check            if(this.isEmpty(sn)) {                document.write("Stack Underflow");                returnNumber.MAX_VALUE;            }            // Find index of top item in stack number 'sn'            vari = this.top[sn];            this.top[sn] = this.next[i]; // Change top to store next of previous top            // Attach the previous top to the beginning of free list            this.next[i] = this.free;            this.free = i;            // Return the previous top item            returnthis.arr[i];        }        // To check whether stack number 'sn' is empty or not         isEmpty(sn) {            return(this.top[sn] == -1);        }    }    // Driver program            // Let us create 3 stacks in an array of size 10        vark = 3;        n = 10;        varks = newKStack(k, n);        ks.push(15, 2);        ks.push(45, 2);        // Let us put some items in stack number 1        ks.push(17, 1);        ks.push(49, 1);        ks.push(39, 1);        // Let us put some items in stack number 0        ks.push(11, 0);        ks.push(9, 0);        ks.push(7, 0);        document.write("Popped element from stack 2 is "+ ks.pop(2));        document.write("<br/>Popped element from stack 1 is "+ ks.pop(1));        document.write("<br/>Popped element from stack 0 is "+ ks.pop(0));// This code is contributed by gauravrajput1</script> | 
Popped element from stack 2 is 45 Popped element from stack 1 is 39 Popped element from stack 0 is 7
Time complexities of operations push() and pop() is O(1). The best part of above implementation is, if there is a slot available in stack, then an item can be pushed in any of the stacks, i.e., no wastage of space.
Time Complexity of top() operation is also O(1)
Time Complexity: O(N), as we are using a loop to traverse N times.
Auxiliary Space: O(N), as we are using extra space for the stack.
This article is contributed by Sachin. Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!


 
                                    







