Skip to content

Commit ab1796b

Browse files
Add stack-based algorithm implementations
Implement four stack-related algorithms: `is_valid` for validating parentheses, `MinStack` for tracking minimum stack values, `evaluate_reverse_polish_notation` for evaluating expressions in postfix notation, and `generate_parentheses` for generating valid parentheses combinations. Each implementation includes corresponding unit tests for validation.
1 parent 9b13221 commit ab1796b

5 files changed

+190
-0
lines changed

Stack/__init__.py

Whitespace-only changes.
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# https://neetcode.io/problems/evaluate-reverse-polish-notation
2+
3+
import unittest
4+
from typing import List
5+
6+
def evaluate_reverse_polish_notation(tokens: List[str]) -> int:
7+
stack = []
8+
9+
for token in tokens:
10+
if token in '+-*/':
11+
# The values are in reverse order, so 'b' is first then 'a' due
12+
# to the order of stack operations
13+
b = stack.pop()
14+
a = stack.pop()
15+
16+
# Perform the computation and push result back onto the stack
17+
18+
if token == '+':
19+
stack.append(a + b)
20+
elif token == '-':
21+
stack.append(a - b)
22+
elif token == '*':
23+
stack.append(a * b)
24+
else:
25+
stack.append(a // b)
26+
27+
continue
28+
29+
stack.append(int(token)) # Convert token to int and push into the stack
30+
31+
return stack.pop() # The final result will be the only element left on the stack
32+
33+
class Test(unittest.TestCase):
34+
def test_evaluate_reverse_polish_notation(self):
35+
self.assertEqual(evaluate_reverse_polish_notation(["1", "2", "+", "3", "*", "4", "-"]), 5)

Stack/generate_parentheses.py

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# https://neetcode.io/problems/generate-parentheses
2+
3+
import unittest
4+
from typing import List
5+
6+
def generate_parentheses(n: int) -> List[str]:
7+
result = []
8+
stack = []
9+
10+
def backtrack(open_count, close_count):
11+
if open_count == close_count == n:
12+
return result.append(''.join(stack))
13+
14+
if open_count < n:
15+
stack.append('(')
16+
backtrack(open_count + 1, close_count)
17+
stack.pop()
18+
19+
if close_count < open_count:
20+
stack.append(')')
21+
backtrack(open_count, close_count + 1)
22+
stack.pop()
23+
24+
backtrack(0, 0)
25+
26+
return result
27+
28+
class Test(unittest.TestCase):
29+
def test_generate_parentheses(self):
30+
self.assertEqual(generate_parentheses(1), ["()"])
31+
self.assertEqual(generate_parentheses(3), ["((()))", "(()())", "(())()", "()(())", "()()()"])

Stack/minimum_stack.py

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# https://neetcode.io/problems/minimum-stack
2+
3+
import unittest
4+
5+
class MinStack:
6+
def __init__(self):
7+
self.stack = []
8+
self.min_stack = []
9+
10+
def push(self, value: int) -> None:
11+
self.stack.append(value)
12+
13+
value = min(value, self.min_stack[-1] if self.min_stack else value)
14+
self.min_stack.append(value)
15+
16+
def pop(self) -> None:
17+
if self.stack:
18+
self.stack.pop()
19+
20+
if self.min_stack:
21+
self.min_stack.pop()
22+
23+
def top(self) -> int:
24+
return self.stack[-1] if self.stack else None
25+
26+
def get_min(self) -> int:
27+
return self.min_stack[-1] if self.min_stack else None
28+
29+
class TestMinStack(unittest.TestCase):
30+
def setUp(self):
31+
self.min_stack = MinStack()
32+
33+
def test_push(self):
34+
self.min_stack.push(3)
35+
self.assertEqual(self.min_stack.top(), 3)
36+
self.assertEqual(self.min_stack.get_min(), 3)
37+
38+
self.min_stack.push(5)
39+
self.assertEqual(self.min_stack.top(), 5)
40+
self.assertEqual(self.min_stack.get_min(), 3)
41+
42+
self.min_stack.push(2)
43+
self.assertEqual(self.min_stack.top(), 2)
44+
self.assertEqual(self.min_stack.get_min(), 2)
45+
46+
self.min_stack.push(2)
47+
self.assertEqual(self.min_stack.top(), 2)
48+
self.assertEqual(self.min_stack.get_min(), 2)
49+
50+
self.min_stack.push(1)
51+
self.assertEqual(self.min_stack.top(), 1)
52+
self.assertEqual(self.min_stack.get_min(), 1)
53+
54+
def test_pop(self):
55+
self.min_stack.push(3)
56+
self.min_stack.push(5)
57+
self.min_stack.push(2)
58+
self.min_stack.push(2)
59+
self.min_stack.push(1)
60+
61+
self.min_stack.pop()
62+
self.assertEqual(self.min_stack.top(), 2)
63+
self.assertEqual(self.min_stack.get_min(), 2)
64+
65+
self.min_stack.pop()
66+
self.assertEqual(self.min_stack.top(), 2)
67+
self.assertEqual(self.min_stack.get_min(), 2)
68+
69+
self.min_stack.pop()
70+
self.assertEqual(self.min_stack.top(), 5)
71+
self.assertEqual(self.min_stack.get_min(), 3)
72+
73+
self.min_stack.pop()
74+
self.assertEqual(self.min_stack.top(), 3)
75+
self.assertEqual(self.min_stack.get_min(), 3)
76+
77+
def test_top(self):
78+
self.min_stack.push(3)
79+
self.assertEqual(self.min_stack.top(), 3)
80+
81+
self.min_stack.push(5)
82+
self.assertEqual(self.min_stack.top(), 5)
83+
84+
def test_get_min(self):
85+
self.min_stack.push(3)
86+
self.assertEqual(self.min_stack.get_min(), 3)
87+
88+
self.min_stack.push(5)
89+
self.assertEqual(self.min_stack.get_min(), 3)
90+
91+
self.min_stack.push(2)
92+
self.assertEqual(self.min_stack.get_min(), 2)
93+
94+
self.min_stack.push(1)
95+
self.assertEqual(self.min_stack.get_min(), 1)
96+

Stack/valid_parentheses.py

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# https://neetcode.io/problems/validate-parentheses
2+
3+
import unittest
4+
5+
def is_valid(s: str) -> bool:
6+
closing = {')': '(', ']': '[', '}': '{'}
7+
stack = []
8+
9+
for char in s:
10+
is_closing = char in closing
11+
12+
if is_closing and (stack and stack[-1] == closing[char]):
13+
stack.pop()
14+
continue
15+
16+
if is_closing and not stack:
17+
return False
18+
19+
stack.append(char)
20+
21+
return len(stack) == 0
22+
23+
class Test(unittest.TestCase):
24+
def test_is_valid(self):
25+
self.assertTrue(is_valid('[]'))
26+
self.assertTrue(is_valid('([{}])'))
27+
self.assertFalse(is_valid('[(])'))
28+
self.assertFalse(is_valid(']'))

0 commit comments

Comments
 (0)