Problem
Implement 3 stacks using a single list:
class Stack:
def __init__(self):
self.list = []
def pop(self, stack_number):
pass
def push(self, item, stack_number):
pass
Solution
Method 1 - Using List
We can use a single list to manage three stacks by using a simple indexing approach. By maintaining separate bounds and pointers (indices) for each stack within the list, we can manage where elements of each stack are pushed and popped.
Approach
- Initialization: Use a single list for storing the data for all three stacks.
- Push Operation:
- Calculate the index where the item should be placed based on the stack number and the current size of that stack.
- Insert the item at the derived index.
- Pop Operation:
- Fetch the last item pushed to the specific stack based on the stack number.
- Return the item and remove it from the list.
- Tracking: Maintain a list of three lists (bounds) to keep track of the current items in each stack.
Code
Java
public class Solution {
public static class Stack {
private List<Integer> list;
private List<List<Integer>> bounds;
public Stack() {
list = new ArrayList<>();
bounds = new ArrayList<>(3);
for (int i = 0; i < 3; i++) {
bounds.add(new ArrayList<>());
}
}
public void push(int item, int stackNumber) {
if (stackNumber < 0 || stackNumber > 2) {
throw new IllegalArgumentException("Invalid stack number");
}
int index = bounds.get(stackNumber).size();
list.add(item);
bounds.get(stackNumber).add(index);
}
public int pop(int stackNumber) {
if (stackNumber < 0 || stackNumber > 2) {
throw new IllegalArgumentException("Invalid stack number");
}
if (bounds.get(stackNumber).isEmpty()) {
throw new IllegalStateException("Stack is empty");
}
int lastIndex = bounds.get(stackNumber).remove(bounds.get(stackNumber).size() - 1);
return list.remove(lastIndex);
}
}
}
Python
class Solution:
class Stack:
def __init__(self):
self.list: List[int] = []
self.bounds: List[List[int]] = [[] for _ in range(3)]
def push(self, item: int, stack_number: int) -> None:
if stack_number < 0 or stack_number > 2:
raise ValueError("Invalid stack number")
self.list.append(item)
self.bounds[stack_number].append(len(self.list) - 1)
def pop(self, stack_number: int) -> int:
if stack_number < 0 or stack_number > 2:
raise ValueError("Invalid stack number")
if not self.bounds[stack_number]:
raise IndexError(f"Stack {stack_number} is empty")
index = self.bounds[stack_number].pop()
return self.list.pop(index)
Complexity
- ⏰ Time complexity:
- Push Operation:
O(1)
for inserting an element at the end of the list. - Pop Operation:
O(1)
for removing the last element from the list. - 🧺 Space complexity:
O(n)
wheren
is the total number of elements pushed across all three stacks.