Skip to content

Commit f0e050e

Browse files
committed
Stacks: MinStack
1 parent ec9b331 commit f0e050e

File tree

4 files changed

+150
-0
lines changed

4 files changed

+150
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
[Arrays and Strings]: docs/arrays-and-strings.md
1414
[Linked Lists]: docs/linked-lists.md
15+
[Stacks and Queues]: docs/stacks-and-queues.md
1516

1617
Collection of pure python algorithm implementations to solve computational problems.
1718

@@ -24,6 +25,7 @@ The goal is for these implementations to be:
2425
## List of problems
2526
- [Arrays and Strings]
2627
- [Linked Lists]
28+
- [Stacks and Queues]
2729

2830
**References**:
2931
- The book [Cracking the Coding Interview, 6th Edition].

docs/stacks-and-queues.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<h1 align="center" style="border-bottom: none;"> Stacks and Queues </h1>
2+
3+
[Stack Min]: ../src/algorithmic/stacks.py#L70
4+
5+
1. **[Stack Min]**: How would you design a stack which, in addition to push and pop, has a function min
6+
which returns the minimum element? Push, pop and min should all operate in 0(1) time.
7+

src/algorithmic/stacks.py

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
from typing import Any
2+
3+
4+
class EmptyStackException(Exception):
5+
pass
6+
7+
8+
class Node:
9+
"""Represents a node of a stack.
10+
11+
Args:
12+
data: the data to save in the node.
13+
"""
14+
def __init__(self, data: Any) -> None:
15+
self.data = data
16+
self.next = None
17+
18+
def __repr__(self) -> str:
19+
return str(self.data)
20+
21+
22+
class Stack:
23+
"""Represents a Stack data structure."""
24+
25+
def __init__(self) -> None:
26+
self._top = None
27+
28+
def pop(self) -> Any:
29+
"""Returns and removes the top of the stack.
30+
31+
Complexity:
32+
- Time: O(1).
33+
- Space: O(1).
34+
"""
35+
if self.is_empty():
36+
raise EmptyStackException()
37+
38+
data = self._top.data
39+
self._top = self._top.next
40+
41+
return data
42+
43+
def peek(self) -> Any:
44+
"""Returns the top of the stack.
45+
46+
Complexity:
47+
- Time: O(1).
48+
- Space: O(1).
49+
"""
50+
if self.is_empty():
51+
raise EmptyStackException()
52+
53+
return self._top.data
54+
55+
def push(self, data: Any) -> None:
56+
"""Adds data to the top of the stack.
57+
58+
Complexity:
59+
- Time: O(1).
60+
- Space: O(1).
61+
"""
62+
new_top = Node(data)
63+
new_top.next = self._top
64+
self._top = new_top
65+
66+
def is_empty(self) -> bool:
67+
return self._top is None
68+
69+
70+
class StackMin(Stack):
71+
"""Implements a Stack with a min method that returns the minimum."""
72+
73+
def push(self, data: Any) -> None:
74+
"""Adds data to the top of the stack.
75+
76+
Complexity:
77+
- Time: O(1).
78+
- Space: O(1).
79+
"""
80+
new_top = Node(data)
81+
new_top.substack_min = data
82+
83+
if not self.is_empty():
84+
if self._top.substack_min < new_top.substack_min:
85+
new_top.substack_min = self._top.substack_min
86+
87+
new_top.next = self._top
88+
self._top = new_top
89+
90+
def min(self) -> Any:
91+
"""Returns the minimum of the stack.
92+
93+
Complexity:
94+
- Time: O(1).
95+
- Space: O(1).
96+
"""
97+
if self.is_empty():
98+
raise EmptyStackException()
99+
100+
return self._top.substack_min

tests/test_stacks.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import pytest
2+
3+
from algorithmic import stacks
4+
5+
6+
def test_stack():
7+
8+
assert repr(stacks.Node(3)) == '3'
9+
10+
stack = stacks.Stack()
11+
stack.push(7)
12+
stack.push(10)
13+
14+
assert stack.pop() == 10
15+
assert stack.peek() == 7
16+
assert stack.pop() == 7
17+
18+
with pytest.raises(stacks.EmptyStackException):
19+
stack.pop()
20+
21+
with pytest.raises(stacks.EmptyStackException):
22+
stack.peek()
23+
24+
25+
def test_stack_min():
26+
stack = stacks.StackMin()
27+
stack.push(7)
28+
stack.push(3)
29+
stack.push(5)
30+
31+
assert stack.min() == 3
32+
33+
stack.pop()
34+
assert stack.min() == 3
35+
36+
stack.pop()
37+
assert stack.min() == 7
38+
39+
stack.pop()
40+
with pytest.raises(stacks.EmptyStackException):
41+
stack.min()

0 commit comments

Comments
 (0)