Open In App

Implement k stacks in an array

Last Updated : 22 Sep, 2025
Comments
Improve
Suggest changes
270 Likes
Like
Report

Given two integers n and k. Implement k stacks using a single array of size n. Multiple stacks must share the same array space while supporting the following operations:

push(x, i): Push element x into the i-th stack.
pop(i): Pop the top element from the i-th stack and return it.

[Naive Approach] Dividing Array into k Segments

The idea is to divide the array into fixed parts, one for each stack. If the array size is n and there are k stacks, then each stack gets n/k slots.

We maintain another array top[] of size k, where top[i] stores the index of the top element of the i-th stack. Initially, all top[i] are set to the start of their respective segments minus one (indicating empty stacks).

Push is done by incrementing top[i] and inserting the element, while pop is done by returning the element at top[i] and then decrementing it.

_Division-of-an-Array-to-Implement-k-Stacks

Limitation: This approach leads to inefficient space utilization, since one stack may become full even when other stacks still have free space available.

C++
#include <iostream>
#include <vector>
using namespace std;

class kStacks {
    
    // main array to store elements
    int *arr;    
    
    // stores top index for each stack
    int *top;    
    
    // size of each segment
    int segSize; 

public:
    kStacks(int n, int k) {
        segSize = n / k;
        arr = new int[n];
        top = new int[k];

        // initialize top pointers
        for (int i = 0; i < k; i++)
            top[i] = i * segSize - 1;
    }

    // push element x into stack i
    void push(int x, int i) {
        int end = (i + 1) * segSize - 1;

        if (top[i] == end) {
            cout << "Stack " << i << " overflow" << endl;
            return;
        }

        top[i]++;
        arr[top[i]] = x;
    }

    // pop element from stack i
    int pop(int i) {
        int start = i * segSize;

        if (top[i] < start) {
            cout << "Stack " << i << " underflow" << endl;
            return -1;
        }

        int val = arr[top[i]];
        top[i]--;
        return val;
    }
};

int main() {
    int n = 4, k = 2;
    kStacks st(n, k);

    // Each operations has the following format:
    // 1. Push operation → {1, value, stackNumber}
    // 2. Pop operation  → {2, stackNumber}
    vector<vector<int>> operations = {
        {1, 5, 0},  
        {1, 9, 0},
        {1, 10, 0}, 
        {1, 15, 1}, 
        {2, 0},
        {2, 1},
        {2, 1}
    };

    for (auto &op : operations) {
        
        if (op[0] == 1) { 
            int x = op[1], m = op[2];
            st.push(x, m);
        } else if (op[0] == 2) { 
            int m = op[1];
            int res = st.pop(m);
            if (res != -1)
                cout << "Popped Element: " << res << endl;
        }
    }

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

class kStacks {

    // main array to store elements
    private int[] arr;

    // stores top index for each stack
    private int[] top;

    // size of each segment
    private int segSize;

    public kStacks(int n, int k) {
        segSize = n / k;
        arr = new int[n];
        top = new int[k];

        // initialize top pointers
        for (int i = 0; i < k; i++)
            top[i] = i * segSize - 1;
    }

    // push element x into stack i
    public void push(int x, int i) {
        int end = (i + 1) * segSize - 1;

        if (top[i] == end) {
            System.out.println("Stack " + i + " overflow");
            return;
        }

        top[i]++;
        arr[top[i]] = x;
    }

    // pop element from stack i
    public int pop(int i) {
        int start = i * segSize;

        if (top[i] < start) {
            System.out.println("Stack " + i + " underflow");
            return -1;
        }

        int val = arr[top[i]];
        top[i]--;
        return val;
    }
}

public class GfG {
    public static void main(String[] args) {
        int n = 4, k = 2;
        kStacks st = new kStacks(n, k);

        // Each operations has the following format:
        // 1. Push operation → {1, value, stackNumber}
        // 2. Pop operation  → {2, stackNumber}
       int[][] operations = {
            {1, 5, 0},
            {1, 9, 0},
            {1, 10, 0},
            {1, 15, 1},
            {2, 0},
            {2, 1},
            {2, 1}
        };
        
        for (int[] op : operations) {
            if (op[0] == 1) {
                int x = op[1], m = op[2];
                st.push(x, m);
            } else if (op[0] == 2) {
                int m = op[1];
                int res = st.pop(m);
                if (res != -1)
                    System.out.println("Popped Element: " + res);
            }
        }
    }
}
Python
class kStacks:

    # main array to store elements
    def __init__(self, n, k):
        self.segSize = n // k
        self.arr = [0] * n
        self.top = [i * self.segSize - 1 for i in range(k)]

    # push element x into stack i
    def push(self, x, i):
        end = (i + 1) * self.segSize - 1

        if self.top[i] == end:
            print(f'Stack {i} overflow')
            return

        self.top[i] += 1
        self.arr[self.top[i]] = x

    # pop element from stack i
    def pop(self, i):
        start = i * self.segSize

        if self.top[i] < start:
            print(f'Stack {i} underflow')
            return -1

        val = self.arr[self.top[i]]
        self.top[i] -= 1
        return val


if __name__ == '__main__':
    n = 4
    k = 2
    st = kStacks(n, k)

    # Each operation has the following format:
    # 1. Push operation → [1, value, stackNumber]
    # 2. Pop operation  → [2, stackNumber]
    operations = [
        [1, 5, 0],
        [1, 9, 0],
        [1, 10, 0],
        [1, 15, 1],
        [2, 0],
        [2, 1],
        [2, 1]
    ]
    
    for op in operations:
        if op[0] == 1:
            x = op[1]
            m = op[2]
            st.push(x, m)
        elif op[0] == 2:
            m = op[1]
            res = st.pop(m)
            if res != -1:
                print(f'Popped Element: {res}')
C#
using System;

class kStacks {

    // main array to store elements
    private int[] arr;

    // stores top index for each stack
    private int[] top;

    // size of each segment
    private int segSize;

    public kStacks(int n, int k) {
        segSize = n / k;
        arr = new int[n];
        top = new int[k];

        // initialize top pointers
        for (int i = 0; i < k; i++)
            top[i] = i * segSize - 1;
    }

    // push element x into stack i
    public void push(int x, int i) {

        int end = (i + 1) * segSize - 1;

        if (top[i] == end) {
            Console.WriteLine("Stack " + i + " overflow");
            return;
        }

        top[i]++;
        arr[top[i]] = x;
    }

    // pop element from stack i
    public int pop(int i) {
        
        int start = i * segSize;

        if (top[i] < start) {
            Console.WriteLine("Stack " + i + " underflow");
            return -1;
        }

        int val = arr[top[i]];
        top[i]--;
        return val;
    }
}

class GfG {
    static void Main() {
        int n = 4, k = 2;
        kStacks st = new kStacks(n, k);

        // Each operation has the following format:
        // 1. Push operation → {1, value, stackNumber}
        // 2. Pop operation  → {2, stackNumber}
        int[][] operations = {
            new int[] {1, 5, 0},
            new int[] {1, 9, 0},
            new int[] {1, 10, 0},
            new int[] {1, 15, 1},
            new int[] {2, 0},
            new int[] {2, 1},
            new int[] {2, 1}
        };
        
        foreach (var op in operations) {
            if (op[0] == 1) {
                int x = op[1], m = op[2];
                st.push(x, m);
            } else if (op[0] == 2) {
                int m = op[1];
                int res = st.pop(m);
                if (res != -1)
                    Console.WriteLine("Popped Element: " + res);
            }
        }
    }
}
JavaScript
class kStacks {

    // main array to store elements
    arr;

    // stores top index for each stack
    top;

    // size of each segment
    segSize;

    constructor(n, k) {
        this.segSize = Math.floor(n / k);
        this.arr = new Array(n);
        this.top = new Array(k);

        // initialize top pointers
        for (let i = 0; i < k; i++)
            this.top[i] = i * this.segSize - 1;
    }

    // push element x into stack i
    push(x, i) {
        const end = (i + 1) * this.segSize - 1;

        if (this.top[i] === end) {
            console.log(`Stack ${i} overflow`);
            return;
        }

        this.top[i]++;
        this.arr[this.top[i]] = x;
    }

    // pop element from stack i
    pop(i) {
        const start = i * this.segSize;

        if (this.top[i] < start) {
            console.log(`Stack ${i} underflow`);
            return -1;
        }

        const val = this.arr[this.top[i]];
        this.top[i]--;
        return val;
    }
}

// Driver Code
const n = 4, k = 2;
const st = new kStacks(n, k);

// Each operation has the following format:
// 1. Push operation → [1, value, stackNumber]
// 2. Pop operation  → [2, stackNumber]
const operations = [
    [1, 5, 0],
    [1, 9, 0],
    [1, 10, 0],
    [1, 15, 1],
    [2, 0],
    [2, 1],
    [2, 1]
];

for (const op of operations) {
    if (op[0] === 1) {
        const x = op[1], m = op[2];
        st.push(x, m);
    } else if (op[0] === 2) {
        const m = op[1];
        const res = st.pop(m);
        if (res !== -1)
            console.log(`Popped Element: ${res}`);
    }
}

Output
Stack 0 overflow
Poped Element: 9
Poped Element: 15
Stack 1 underflow

Time Complexity: O(1) for push operation and pop operation
Auxiliary Space: O(n)

[Efficient Approach] Using Space Optimized Method

The idea is to allow all stacks to share the array dynamically instead of dividing it into fixed parts. For this, we use three additional structures:

  • An array top[] of size k, where top[i] stores the index of the top element of the i-th stack.
  • An array next[] of size n, which links free slots together and also helps connect elements within a stack.
  • A variable freeTop that stores the index of the first free slot in the array.

Push Operation:
When we push an element into stack i, we pick the first free slot from freeTop. The element is placed at this index, and the next[] array is updated to link this slot with the previous top of stack i. Finally, top[i] is updated to this new index, and freeTop moves to the next available free slot.

Pop Operation:
When we pop from stack i, we look at the index stored in top[i]. The element at that index is removed, and top[i] is updated to the next link stored in next[]. The freed index is then added back to the free list by updating freeTop.

 Illustrations:


C++
#include <iostream>
using namespace std;

class kStacks {
    
    // main array to store elements
    int *arr;

    // array to store indexes of top elements of stacks
    int *top;

    // array to store next entry (for free list and stack links)
    int *next;

    // beginning index of free list
    int freeTop;

public:
    kStacks(int n, int k) {
        arr = new int[n];
        top = new int[k];
        next = new int[n];

        // initialize tops of all stacks as empty
        for (int i = 0; i < k; i++)
            top[i] = -1;

        // initialize free list
        freeTop = 0;
        for (int i = 0; i < n - 1; i++)
            next[i] = i + 1;
        next[n - 1] = -1;
    }

    // push element x into stack i
    void push(int x, int i) {
        if (freeTop == -1) {
            cout << "Stack Overflow\n";
            return;
        }

        // take index from free list
        int index = freeTop;     
        
        // update free list
        freeTop = next[index];
        
        // put element in array
        arr[index] = x;          
        
        // link new element to previous top
        next[index] = top[i];    
        
        // update top of stack
        top[i] = index;          
    }

    // pop element from stack i
    int pop(int i) {
        if (top[i] == -1) {
            cout << "Stack Underflow\n";
            return -1;
        }

        // get top index
        int index = top[i];      
        
        // update top to next element
        top[i] = next[index];    

        // add index back to free list
        next[index] = freeTop;   
        freeTop = index;

        // return popped element
        return arr[index];       
    }
};

int main() {
    int n = 9, k = 3;
    kStacks st(n, k);

    // Each query has the following format:
    // 1. Push operation → {1, value, stackNumber}
    // 2. Pop operation  → {2, stackNumber}
    int operations[][3] = {
        {1, 10, 1},
        {1, 20, 1},
        {1, 30, 1},
        {1, 100, 0},
        {1, 200, 0},
        {2, 1},
        {2, 1},
        {2, 0},
        {1, 2, 2}
    };
    
    int op = sizeof(operations) / sizeof(operations[0]);
    
    for (int i = 0; i < op; i++) {
        if (operations[i][0] == 1) {
            int x = operations[i][1], m = operations[i][2];
            st.push(x, m);
        } else if (operations[i][0] == 2) {
            int m = operations[i][1];
            int res = st.pop(m);
            if (res != -1)
                cout << "Popped Element: " << res << endl;
        }
    }

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

class kStacks {

    // main array to store elements
    private int[] arr;

    // array to store indexes of top elements of stacks
    private int[] top;

    // array to store next entry (for free list and stack links)
    private int[] next;

    // beginning index of free list
    private int freeTop;

    public kStacks(int n, int k) {
        arr = new int[n];
        top = new int[k];
        next = new int[n];

        // initialize tops of all stacks as empty
        Arrays.fill(top, -1);

        // initialize free list
        freeTop = 0;
        for (int i = 0; i < n - 1; i++)
            next[i] = i + 1;
        next[n - 1] = -1;
    }

    // push element x into stack i
    public void push(int x, int i) {
        if (freeTop == -1) {
            System.out.println("Stack Overflow");
            return;
        }

        // take index from free list
        int index = freeTop;

        // update free list
        freeTop = next[index];

        // put element in array
        arr[index] = x;

        // link new element to previous top
        next[index] = top[i];

        // update top of stack
        top[i] = index;
    }

    // pop element from stack i
    public int pop(int i) {
        if (top[i] == -1) {
            System.out.println("Stack Underflow");
            return -1;
        }

        // get top index
        int index = top[i];

        // update top to next element
        top[i] = next[index];

        // add index back to free list
        next[index] = freeTop;
        freeTop = index;

        // return popped element
        return arr[index];
    }
}

public class Main {
    public static void main(String[] args) {
        int n = 9, k = 3;
        kStacks st = new kStacks(n, k);

        // Each operation has the following format:
        // 1. Push operation → {1, value, stackNumber}
        // 2. Pop operation  → {2, stackNumber}
        int[][] operations = {
            {1, 10, 1},
            {1, 20, 1},
            {1, 30, 1},
            {1, 100, 0},
            {1, 200, 0},
            {2, 1},
            {2, 1},
            {2, 0},
            {1, 2, 2}
        };
        
        int op = operations.length;
        
        for (int i = 0; i < op; i++) {
            if (operations[i][0] == 1) {
                int x = operations[i][1], m = operations[i][2];
                st.push(x, m);
            } else if (operations[i][0] == 2) {
                int m = operations[i][1];
                int res = st.pop(m);
                if (res != -1)
                    System.out.println("Popped Element: " + res);
            }
        }
    }
}
Python
class kStacks:

    def __init__(self, n, k):
        self.arr = [0] * n
        self.top = [-1] * k
        self.next = [0] * n
        self.freeTop = 0

        for i in range(n - 1):
            self.next[i] = i + 1
        self.next[n - 1] = -1

    def push(self, x, i):
        if self.freeTop == -1:
            print("Stack Overflow")
            return

        index = self.freeTop
        self.freeTop = self.next[index]
        self.arr[index] = x
        self.next[index] = self.top[i]
        self.top[i] = index

    def pop(self, i):
        if self.top[i] == -1:
            print("Stack Underflow")
            return -1

        index = self.top[i]
        self.top[i] = self.next[index]
        self.next[index] = self.freeTop
        self.freeTop = index

        return self.arr[index]


if __name__ == '__main__':
    n = 9
    k = 3
    st = kStacks(n, k)

    # Each operation has the following format:
    # 1. Push operation → (1, value, stackNumber)
    # 2. Pop operation  → (2, stackNumber)
    operations = [
        (1, 10, 1),
        (1, 20, 1),
        (1, 30, 1),
        (1, 100, 0),
        (1, 200, 0),
        (2, 1),
        (2, 1),
        (2, 0),
        (1, 2, 2)
    ]
    
    for op in operations:
        if op[0] == 1:
            x, m = op[1], op[2]
            st.push(x, m)
        elif op[0] == 2:
            m = op[1]
            res = st.pop(m)
            if res != -1:
                print(f'Popped Element: {res}')
C#
using System;

public class kStacks {
    
    // main array to store elements
    private int[] arr;

    // array to store indexes of top elements of stacks
    private int[] top;

    // array to store next entry (for free list and stack links)
    private int[] next;

    // beginning index of free list
    private int freeTop;

    public kStacks(int n, int k) {
        arr = new int[n];
        top = new int[k];
        next = new int[n];

        // initialize tops of all stacks as empty
        for (int i = 0; i < k; i++)
            top[i] = -1;

        // initialize free list
        freeTop = 0;
        for (int i = 0; i < n - 1; i++)
            next[i] = i + 1;
        next[n - 1] = -1;
    }

    // push element x into stack i
    public void push(int x, int i) {
        if (freeTop == -1) {
            Console.WriteLine("Stack Overflow");
            return;
        }

        // take index from free list
        int index = freeTop;

        // update free list
        freeTop = next[index];

        // put element in array
        arr[index] = x;

        // link new element to previous top
        next[index] = top[i];

        // update top of stack
        top[i] = index;
    }

    // pop element from stack i
    public int pop(int i) {
        if (top[i] == -1) {
            Console.WriteLine("Stack Underflow");
            return -1;
        }

        // get top index
        int index = top[i];

        // update top to next element
        top[i] = next[index];

        // add index back to free list
        next[index] = freeTop;
        freeTop = index;

        // return popped element
        return arr[index];
    }
}

public class GfG {
    public static void Main(string[] args) {
        int n = 9, k = 3;
        kStacks st = new kStacks(n, k);

        // Each operation has the following format:
        // 1. Push operation → {1, value, stackNumber}
        // 2. Pop operation  → {2, stackNumber}
        int[][] operations = {
            new int[] {1, 10, 1},
            new int[] {1, 20, 1},
            new int[] {1, 30, 1},
            new int[] {1, 100, 0},
            new int[] {1, 200, 0},
            new int[] {2, 1},
            new int[] {2, 1},
            new int[] {2, 0},
            new int[] {1, 2, 2}
        };
        
        int opCount = operations.Length;
        
        for (int i = 0; i < opCount; i++) {
            if (operations[i][0] == 1) {
                int x = operations[i][1], m = operations[i][2];
                st.push(x, m);
            }
            else if (operations[i][0] == 2) {
                int m = operations[i][1];
                int res = st.pop(m);
                if (res != -1)
                    Console.WriteLine("Popped Element: " + res);
            }
        }
    }
}
JavaScript
class kStacks {
    // main array to store elements
    arr;

    // array to store indexes of top elements of stacks
    top;

    // array to store next entry (for free list and stack links)
    next;

    // beginning index of free list
    freeTop;

    constructor(n, k) {
        this.arr = new Array(n);
        this.top = new Array(k);
        this.next = new Array(n);

        // initialize tops of all stacks as empty
        for (let i = 0; i < k; i++)
            this.top[i] = -1;

        // initialize free list
        this.freeTop = 0;
        for (let i = 0; i < n - 1; i++)
            this.next[i] = i + 1;
        this.next[n - 1] = -1;
    }

    // push element x into stack i
    push(x, i) {
        if (this.freeTop === -1) {
            console.log('Stack Overflow');
            return;
        }

        // take index from free list
        let index = this.freeTop;

        // update free list
        this.freeTop = this.next[index];

        // put element in array
        this.arr[index] = x;

        // link new element to previous top
        this.next[index] = this.top[i];

        // update top of stack
        this.top[i] = index;
    }

    // pop element from stack i
    pop(i) {
        if (this.top[i] === -1) {
            console.log('Stack Underflow');
            return -1;
        }

        // get top index
        let index = this.top[i];

        // update top to next element
        this.top[i] = this.next[index];

        // add index back to free list
        this.next[index] = this.freeTop;
        this.freeTop = index;

        // return popped element
        return this.arr[index];
    }
}

// Driver Code
let n = 9, k = 3;
let st = new kStacks(n, k);

// Each operation has the following format:
// 1. Push operation → [1, value, stackNumber]
// 2. Pop operation  → [2, stackNumber]
let operations = [
    [1, 10, 1],
    [1, 20, 1],
    [1, 30, 1],
    [1, 100, 0],
    [1, 200, 0],
    [2, 1],
    [2, 1],
    [2, 0],
    [1, 2, 2]
];

let opCount = operations.length;

for (let i = 0; i < opCount; i++) {
    if (operations[i][0] === 1) {
        let x = operations[i][1], m = operations[i][2];
        st.push(x, m);
    } else if (operations[i][0] === 2) {
        let m = operations[i][1];
        let res = st.pop(m);
        if (res !== -1)
            console.log('Popped Element: ' + res);
    }
}

Output
Popped Element: 30
Popped Element: 20
Popped Element: 200

Time Complexity: O(1) for push operation and pop operation
Auxiliary Space: O(n)

Related Article:


Article Tags :

Explore