Data Structures
Algorithms
Stacks
Array Implementation
Computer Science

How to implement 3 stacks with one array?

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

Introduction

Implementing three stacks in one array is a classic data-structure exercise because it forces you to manage shared storage explicitly. The best implementation depends on whether you want simplicity or flexibility: a fixed partition is easy to code, while a dynamic layout uses space better at the cost of more bookkeeping.

Fixed Partition Design

The simplest design is to divide the array into three equal sections and dedicate one section to each stack. Each stack keeps its own size or top pointer.

python
1class ThreeStacks:
2    def __init__(self, stack_capacity: int):
3        self.stack_capacity = stack_capacity
4        self.values = [None] * (stack_capacity * 3)
5        self.sizes = [0, 0, 0]
6
7    def _index_of_top(self, stack_num: int) -> int:
8        offset = stack_num * self.stack_capacity
9        size = self.sizes[stack_num]
10        return offset + size - 1
11
12    def push(self, stack_num: int, value):
13        if self.sizes[stack_num] == self.stack_capacity:
14            raise IndexError("stack is full")
15
16        self.sizes[stack_num] += 1
17        self.values[self._index_of_top(stack_num)] = value
18
19    def pop(self, stack_num: int):
20        if self.sizes[stack_num] == 0:
21            raise IndexError("stack is empty")
22
23        top_index = self._index_of_top(stack_num)
24        value = self.values[top_index]
25        self.values[top_index] = None
26        self.sizes[stack_num] -= 1
27        return value
28
29    def peek(self, stack_num: int):
30        if self.sizes[stack_num] == 0:
31            raise IndexError("stack is empty")
32        return self.values[self._index_of_top(stack_num)]

This is the usual interview baseline because the indexing logic is straightforward.

Why Fixed Partitions Are Attractive

This design has clear strengths:

  • constant-time push, pop, and peek
  • easy indexing math
  • simple correctness reasoning

If each stack has a known maximum capacity, fixed partitioning is often good enough in real code too.

The Main Weakness

The downside is wasted space. One stack can fill up and overflow even when the other two stacks are mostly empty. That is the tradeoff for simplicity.

For example, if each partition has capacity 10, then stack 0 cannot grow past 10 items even if stacks 1 and 2 together only use two total slots.

A More Flexible Design

If you want the three stacks to share space dynamically, you need extra metadata. One practical way is to store nodes in one array and maintain linked-list-style stack tops plus a free-list.

python
1class MultiStack:
2    def __init__(self, capacity: int):
3        self.values = [None] * capacity
4        self.next_index = list(range(1, capacity)) + [-1]
5        self.tops = [-1, -1, -1]
6        self.free = 0
7
8    def push(self, stack_num: int, value):
9        if self.free == -1:
10            raise IndexError("array is full")
11
12        insert_at = self.free
13        self.free = self.next_index[insert_at]
14
15        self.values[insert_at] = value
16        self.next_index[insert_at] = self.tops[stack_num]
17        self.tops[stack_num] = insert_at
18
19    def pop(self, stack_num: int):
20        top = self.tops[stack_num]
21        if top == -1:
22            raise IndexError("stack is empty")
23
24        self.tops[stack_num] = self.next_index[top]
25        value = self.values[top]
26
27        self.values[top] = None
28        self.next_index[top] = self.free
29        self.free = top
30
31        return value

This uses one physical array more efficiently because any stack can consume any free slot.

Tradeoffs Between the Two Approaches

The fixed partition method is better when:

  • capacities are known in advance
  • implementation simplicity matters most
  • predictability is more important than perfect space efficiency

The dynamic shared-space method is better when:

  • stack growth is uneven
  • total capacity matters more than per-stack boundaries
  • you are willing to manage extra bookkeeping

Both still support constant-time stack operations.

Validating Stack Numbers

No matter which design you choose, validate the stack identifier before indexing internal arrays.

python
def check_stack_num(stack_num: int):
    if stack_num not in (0, 1, 2):
        raise ValueError("stack number must be 0, 1, or 2")

This is a small detail, but it prevents silent corruption in implementations that assume exactly three stacks.

Common Pitfalls

The biggest pitfall in fixed partitions is off-by-one indexing. Stack boundaries are easy to get wrong if the top index calculation is not carefully defined.

Another issue is forgetting the wasted-space tradeoff. A correct fixed-partition implementation can still be the wrong design if one stack grows much faster than the others.

In the dynamic design, the main risk is corrupting the free-list or next pointers during push and pop. That kind of bug can make one mistake spread through the whole structure.

Finally, do not overengineer the problem. If the exercise or real system only needs a simple bounded solution, the fixed partition design is often the right answer.

Summary

  • The simplest implementation divides one array into three fixed regions.
  • Fixed partitions are easy to reason about but can waste space.
  • A dynamic shared-space design uses extra metadata to let all three stacks share capacity.
  • Both approaches can support constant-time stack operations.
  • Choose the design based on whether simplicity or flexible space usage matters more.

Related reading
Course
Intermediate
27 lessons
15 hours
DSA Fundamentals

Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Data Structures & Algorithms practice on Codemia

Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.

Practice algorithms

All Rights Reserved.