Implement two Stacks in an Array (original) (raw)

Last Updated : 20 Apr, 2026

Create a data structure **twoStacks that represent two stacks. Implementation of twoStacks should use only one array, i.e., both stacks should use the same array for storing elements.

Following functions must be supported by twoStacks.

**Examples:

**Input: push1(2), push1(3), push2(4), pop1(), pop2(), pop2()
**Output: [3, 4, -1]
**Explanation: push1(2) the stack1 will be [2]
push1(3) the stack1 will be [2,3]
push2(4) the stack2 will be [4]
pop1() the popped element will be 3 from stack1 and stack1 will be [2]
pop2() the popped element will be 4 from stack2 and now stack2 is empty
pop2() the stack2 is now empty hence returned -1

**Input: push1(1), push2(2), pop1(), push1(3), pop1(), pop1()
**Output: [1, 3, -1]
**Explanation: push1(1) the stack1 will be [1]
push2(2) the stack2 will be [2]
pop1() the popped element will be 1
push1(3) the stack1 will be [3]
pop1() the popped element will be 3
pop1() the stack1 is now empty hence returned -1

Try It Yourselfredirect icon

Table of Content

**[Naive Approach] Dividing the space into two halves

The idea to implement two stacks is to divide the array into two halves and assign two halves to two stacks, i.e., use arr[0] to arr[n/2] for stack1, and arr[(n/2) + 1] to arr[n-1] for stack2 where arr[] is the array to be used to implement two stacks and size of array be n.

Follow the steps below to solve the problem:

To implement **push1(x):

To implement **push2(x):

To implement **pop1():

To implement **pop2():

#include #include <stdlib.h>

using namespace std;

class twoStacks { int *arr; int size; int mid; int top1, top2;

public: twoStacks(int n) { size = n; arr = new int[n]; mid = n / 2;

    // top1 starts from 0
    top1 = -1;

    // top2 starts from mid
    top2 = mid - 1;
}

void push1(int x)
{
    if (top1 == mid - 1)
    {
        // top1 reaches middle of the array
        // so stack1 is full
        return;
    }
    top1++;
    arr[top1] = x;
}

void push2(int x)
{
    if (top2 == size - 1)
    {
        // top2 reaches end of the array
        // so stack2 is full
        return;
    }
    top2++;
    arr[top2] = x;
}

int pop1()
{
    if (top1 == -1)
    {
        // that means stack1 in empty so return -1
        return -1;
    }
    int ele = arr[top1];
    top1--;
    return ele;
}

int pop2()
{
    if (top2 == mid - 1)
    {
        // that means stack2 in empty so return -1
        return -1;
    }
    int ele = arr[top2];
    top2--;
    return ele;
}

};

int main() { twoStacks ts(5); ts.push1(2); ts.push1(3); ts.push2(4); cout << ts.pop1() << " "; cout << ts.pop2() << " "; cout << ts.pop2() << " "; return 0; }

Java

class twoStacks { int[] arr; int size; int mid; int top1, top2;

twoStacks(int n)
{
    size = n;
    arr = new int[n];
    mid = n / 2;
    
    // top1 starts from 0
    top1 = -1;

    // top2 starts from mid
    top2 = mid - 1;
}

void push1(int x)
{
    if (top1 == mid - 1) {
        
        // top1 reaches middle of the array
        // so stack1 is full
        return;
    }
    top1++;
    arr[top1] = x;
}

void push2(int x)
{
    if (top2 == size - 1) {
        
        // top2 reaches end of the array
        // so stack2 is full
        return;
    }
    top2++;
    arr[top2] = x;
}

int pop1()
{
    if (top1 == -1) {
        
        // that means stack in empty so return -1
        return -1;
    }
    int ele = arr[top1];
    top1--;
    return ele;
}

int pop2()
{
    if (top2 == mid - 1) {
        
        // that means stack in empty so return -1
        return -1;
    }
    int ele = arr[top2];
    top2--;
    return ele;
}

}

public class Main { public static void main(String[] args) { twoStacks ts = new twoStacks(5); ts.push1(2); ts.push1(3); ts.push2(4); System.out.print(ts.pop1() + " "); System.out.print(ts.pop2() + " "); System.out.print(ts.pop2() + " "); } }

Python

class TwoStacks: def init(self, n): self.size = n self.arr = [0] * n self.mid = n // 2

    # top1 starts from 0
    self.top1 = -1      
    
    # top2 starts from mid
    self.top2 = self.mid - 1  

def push1(self, x):
    if self.top1 == self.mid - 1:
        
        # top1 reaches middle of the array
        # so stack1 is full
        return
    self.top1 += 1
    self.arr[self.top1] = x

def push2(self, x):
    if self.top2 == self.size - 1:
        
        # top2 reaches end of the array
        # so stack2 is full
        return
    self.top2 += 1
    self.arr[self.top2] = x

def pop1(self):
    if self.top1 == -1:
        
        # that means stack in empty so return -1
        return -1
    ele = self.arr[self.top1]
    self.top1 -= 1
    return ele

def pop2(self):
    if self.top2 == self.mid - 1:
        
        # that means stack in empty so return -1
        return -1
    ele = self.arr[self.top2]
    self.top2 -= 1
    return ele

if name == 'main': ts = TwoStacks(5) ts.push1(2) ts.push1(3) ts.push2(4) print(ts.pop1(), end=' ') print(ts.pop2(), end=' ') print(ts.pop2(), end=' ')

C#

using System;

class twoStacks { int[] arr; int size; int mid; int top1, top2;

public twoStacks(int n)
{
    size = n;
    arr = new int[n];
    mid = n / 2;

    // top1 starts from 0
    top1 = -1;

    // top2 starts from mid
    top2 = mid - 1;
}

public void push1(int x)
{
    if (top1 == mid - 1) {
        
        // top1 reaches middle of the array
        // so stack1 is full
        return;
    }
    top1++;
    arr[top1] = x;
}

public void push2(int x)
{
    if (top2 == size - 1) {
        
        // top2 reaches end of the array
        // so stack2 is full
        return;
    }
    top2++;
    arr[top2] = x;
}

public int pop1()
{
    if (top1 == -1) {
        
        // that means stack1 in empty so return -1
        return -1;
    }
    int ele = arr[top1];
    top1--;
    return ele;
}

public int pop2()
{
    if (top2 == mid - 1) {
        
        // that means stack2 in empty so return -1
        return -1;
    }
    int ele = arr[top2];
    top2--;
    return ele;
}

}

class Program { static void Main() { twoStacks ts = new twoStacks(5); ts.push1(2); ts.push1(3); ts.push2(4); Console.Write(ts.pop1() + " "); Console.Write(ts.pop2() + " "); Console.Write(ts.pop2() + " "); } }

JavaScript

class TwoStacks { constructor(n) { this.size = n; this.arr = new Array(n); this.mid = n / 2;

    // top1 starts from 0
    this.top1 = -1; 
    
    // top2 starts from mid
    this.top2 = Math.floor(this.mid) - 1; 
}

push1(x)
{
    if (this.top1 === Math.floor(this.mid) - 1) {
        
        // top1 reaches middle of the array
        // so stack1 is full
        return;
    }
    this.top1++;
    this.arr[this.top1] = x;
}

push2(x)
{
    if (this.top2 === this.size - 1) {
        
        // top2 reaches end of the array
        // so stack2 is full
        return;
    }
    this.top2++;
    this.arr[this.top2] = x;
}

pop1()
{
    if (this.top1 === -1) {
        
        // that means stack1 in empty so return -1
        return -1;
    }
    let ele = this.arr[this.top1];
    this.top1--;
    return ele;
}

pop2()
{
    if (this.top2 === Math.floor(this.mid) - 1) {
        
        // that means stack2 in empty so return -1
        return -1;
    }
    let ele = this.arr[this.top2];
    this.top2--;
    return ele;
}

}

const ts = new TwoStacks(5); ts.push1(2); ts.push1(3); ts.push2(4);

let res = ""; res += ts.pop1() + " "; res += ts.pop2() + " "; res += ts.pop2() + " "; console.log(res.trim());

`

**Time Complexity:

**Auxiliary Space: O(n), Use of array to implement stack.

Problem in the above implementation

The problem with the approach is that we divide the array into two fixed halves, with one half reserved for stack1 and the other half for stack2. This can lead to inefficient space usage because if stack1 fills up, it cannot use the space available in the second half of the array for stack2, even if that space is not fully utilized.

To fix this, we should allow both stacks to grow dynamically towards each other. Instead of reserving a fixed half for each stack, stack1 will start from the left side of the array, and stack2 will start from the right side. They will grow towards each other. This way, if one stack fills up, the other stack can still use the remaining space. Overflow will only occur when both stacks meet in the middle.

**[Expected Approach] Starting from endpoints

The idea is to start two stacks from two extreme corners of arr[].

Follow the steps below to solve the problem:

#include using namespace std;

class twoStacks { int *arr; int size;
int top1, top2;

public: twoStacks(int n) { size = n; arr = new int[n];

    // Stack1 starts from left (-1 means empty)
    top1 = -1;     
    
    // Stack2 starts from right (size means empty)
    top2 = size;    
}

// Function to push element into Stack1
void push1(int x)
{
    // Check if there is space between two stacks
    if (top1 < top2 - 1)
    {
        // move top1 forward
        top1++;            
        arr[top1] = x;
    }
}

// Function to push element into Stack2
void push2(int x)
{
    // Check if there is space between two stacks
    if (top1 < top2 - 1)
    {
        // move top2 backward
        top2--;            
        arr[top2] = x;
    }
}

// Function to pop element from Stack1
int pop1()
{
    // Check if Stack1 is empty
    if (top1 >= 0)
    {
        int x = arr[top1];
        top1--;           
        return x;
    }
    else
        return -1;
}

// Function to pop element from Stack2
int pop2()
{
    // Check if Stack2 is empty
    if (top2 < size)
    {
        int x = arr[top2];
        top2++;           
        return x;
    }
    else
        return -1;
}

};

int main() { twoStacks ts(5);

ts.push1(2);
ts.push1(3);
ts.push2(4);
cout << ts.pop1() << " ";
cout << ts.pop2() << " ";
cout << ts.pop2() << " ";

return 0;

}

Java

import java.util.Arrays;

class twoStacks { int[] arr; int size; int top1, top2;

twoStacks(int n)
{
    size = n;
    arr = new int[n];
    Arrays.fill(arr, -1);
    
    // Stack1 starts from left (-1 means empty)
    top1 = -1;     
    
    // Stack2 starts from right (size means empty)
    top2 = size;
}

// Function to push element into Stack1
void push1(int x)
{
    // Check if there is space between two stacks
    if (top1 < top2 - 1) {
        
        // move top1 forward
        top1++;            
        arr[top1] = x;
    }
}

// Function to push element into Stack2
void push2(int x)
{
    // Check if there is space between two stacks
    if (top1 < top2 - 1) {
        
        // move top2 backward
        top2--;            
        arr[top2] = x;    
    }
}

// Function to pop element from Stack1
int pop1()
{
    // Check if Stack1 is empty
    if (top1 >= 0) {
        int x = arr[top1];
        top1--;
        return x;
    }
    else
        return -1;
}

// Function to pop element from Stack2
int pop2()
{
    // Check if Stack2 is empty
    if (top2 < size) {
        int x = arr[top2];
        top2++;
        return x;
    }
    else
        return -1;
}

}

public class Main { public static void main(String[] args) { twoStacks ts = new twoStacks(5); ts.push1(2); ts.push1(3); ts.push2(4);

    System.out.print(ts.pop1() + " ");
    System.out.print(ts.pop2() + " ");
    System.out.print(ts.pop2() + " ");
}

}

Python

class TwoStacks: def init(self, n): self.size = n self.arr = [0] * n

    # Stack1 starts from left(-1 means empty)
    self.top1 = -1
    
    # Stack2 starts from right(size means empty)
    self.top2 = n      

# Function to push element into Stack1
def push1(self, x):
    
    # Check if there is space between two stacks
    if self.top1 < self.top2 - 1:
        
        # move top1 forward
        self.top1 += 1             
        self.arr[self.top1] = x

# Function to push element into Stack2
def push2(self, x):
    
    # Check if there is space between two stacks
    if self.top1 < self.top2 - 1:
        
        # move top2 backward
        self.top2 -= 1             
        self.arr[self.top2] = x

# Function to pop element from Stack1
def pop1(self):
    
    # Check if Stack1 is empty
    if self.top1 >= 0:
        x = self.arr[self.top1]
        self.top1 -= 1
        return x
    return -1

# Function to pop element from Stack2
def pop2(self):
    
    # Check is Stack2 is empty
    if self.top2 < self.size:
        x = self.arr[self.top2]
        self.top2 += 1
        return x
    return -1

if name == 'main': ts = TwoStacks(5) ts.push1(2) ts.push1(3) ts.push2(4)

print(ts.pop1(), end=' ')
print(ts.pop2(), end=' ')
print(ts.pop2(), end=' ')

C#

using System;

class twoStacks { int[] arr; int size; int top1, top2;

public twoStacks(int n)
{
    size = n;
    arr = new int[n];
    
    // Stack1 starts from left (-1 means empty)
    top1 = -1;     
    
    // Stack2 starts from right (size means empty)
    top2 = size;
}

// Function to push element into Stack1
public void push1(int x)
{
    // Check if there is space between two stacks
    if (top1 < top2 - 1) {
        
        // move top1 forward
        top1++; 
        arr[top1] = x;
    }
}

// Function to push element into Stack2
public void push2(int x)
{
    // Check if there is space between two stacks
    if (top1 < top2 - 1) {
        
        // move top2 backward
        top2--; 
        arr[top2] = x;
    }
}

// Function to pop element from Stack1
public int pop1()
{
    // Check if Stack1 is empty
    if (top1 >= 0) {
        int x = arr[top1];
        top1--;
        return x;
    }
    else
        return -1;
}

// Function to pop element from Stack2
public int pop2()
{
    // Check if Stack2 is empty
    if (top2 < size) {
        int x = arr[top2];
        top2++;
        return x;
    }
    else
        return -1;
}

}

class Program { static void Main() { twoStacks ts = new twoStacks(5); ts.push1(2); ts.push1(3); ts.push2(4);

    Console.Write(ts.pop1() + " ");
    Console.Write(ts.pop2() + " ");
    Console.Write(ts.pop2() + " ");
}

}

JavaScript

class TwoStacks { constructor(n) { this.size = n; this.arr = new Array(n);

    // Stack1 starts from left (-1 means empty)
    this.top1 = -1; 
    
    // Stack2 starts from right (size means empty)
    this.top2 = n; 
}

// Function to push element into Stack1
push1(x)
{
    // Check if there is space between two stacks
    if (this.top1 < this.top2 - 1) {
        
        // move top1 forward
        this.top1++; 
        this.arr[this.top1] = x;
    }
}

// Function to push element into Stack2
push2(x)
{
    // Check if there is space between two stacks
    if (this.top1 < this.top2 - 1) {
        
        // move top2 backward
        this.top2--; 
        this.arr[this.top2] = x;
    }
}

// Function to pop element from Stack1
pop1()
{
    // Check if Stack1 is empty
    if (this.top1 >= 0) {
        const x = this.arr[this.top1];
        this.top1--;
        return x;
    }
    else {
        return -1;
    }
}

// Function to pop element from Stack2
pop2()
{
    // Check if Stack2 is empty
    if (this.top2 < this.size) {
        const x = this.arr[this.top2];
        this.top2++;
        return x;
    }
    else {
        return -1;
    }
}

}

const ts = new TwoStacks(5); ts.push1(2); ts.push1(3); ts.push2(4);

let output = ""; output += ts.pop1() + " "; output += ts.pop2() + " "; output += ts.pop2() + " ";

console.log(output.trim());

`

**Time Complexity:

**Auxiliary Space: O(n), Use of the array to implement stack.