Skip to content

Commit cea1212

Browse files
committed
CTCI 3.2/3.3
Python solutions
1 parent 20b0057 commit cea1212

File tree

4 files changed

+222
-1
lines changed

4 files changed

+222
-1
lines changed

CTCI/Chapter3/3.1-Three_In_One.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,43 @@ def pop(self, stack_number):
2929
#-------------------------------------------------------------------------------
3030
# CTCI Solution
3131

32+
class MultiStack:
33+
34+
def __init__(self, stacksize):
35+
self.numstacks = 3
36+
self.array = [0] * (stacksize * self.numstacks)
37+
self.sizes = [0] * self.numstacks
38+
self.stacksize = stacksize
39+
40+
def Push(self, item, stacknum):
41+
if self.IsFull(stacknum):
42+
raise Exception('Stack is full')
43+
self.sizes[stacknum] += 1
44+
self.array[self.IndexOfTop(stacknum)] = item
45+
46+
def Pop(self, stacknum):
47+
if self.IsEmpty(stacknum):
48+
raise Exception('Stack is empty')
49+
value = self.array[self.IndexOfTop(stacknum)]
50+
self.array[self.IndexOfTop(stacknum)] = 0
51+
self.sizes[stacknum] -= 1
52+
return value
53+
54+
def Peek(self, stacknum):
55+
if self.IsEmpty(stacknum):
56+
raise Exception('Stack is empty')
57+
return self.array[self.IndexOfTop(stacknum)]
58+
59+
def IsEmpty(self, stacknum):
60+
return self.sizes[stacknum] == 0
61+
62+
def IsFull(self, stacknum):
63+
return self.sizes[stacknum] == self.stacksize
64+
65+
def IndexOfTop(self, stacknum):
66+
offset = stacknum * self.stacksize
67+
return offset + self.sizes[stacknum] - 1
68+
3269
#-------------------------------------------------------------------------------
3370
#Testing
3471

CTCI/Chapter3/3.2-Stack_Min.py

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
# CTCI 3.1
2+
# Three in One
3+
4+
import unittest
5+
6+
class MinStack():
7+
def __init__(self):
8+
self.top, self._min = None, None
9+
10+
def min(self):
11+
if self._min:
12+
return self._min.data
13+
else:
14+
return None
15+
16+
def push(self, item):
17+
if self._min and item >= self._min.data:
18+
self._min = Node(data=self._min.data, next=self._min)
19+
else:
20+
self._min = Node(data=item, next=self.top)
21+
self.top = Node(data=item, next=self.top)
22+
23+
def pop(self):
24+
if not self.top:
25+
return None
26+
else:
27+
self._min = self._min.next
28+
item = self.top.data
29+
self.top = self.top.next
30+
return item
31+
32+
33+
34+
#-------------------------------------------------------------------------------
35+
# CTCI Solution
36+
37+
class MultiStack:
38+
39+
def __init__(self, stacksize):
40+
self.numstacks = 1
41+
self.array = [0] * (stacksize * self.numstacks)
42+
self.sizes = [0] * self.numstacks
43+
self.stacksize = stacksize
44+
self.minvals = [sys.maxint] * (stacksize * self.numstacks)
45+
46+
def Push(self, item, stacknum):
47+
if self.IsFull(stacknum):
48+
raise Exception('Stack is full')
49+
self.sizes[stacknum] += 1
50+
if self.IsEmpty(stacknum):
51+
self.minvals[self.IndexOfTop(stacknum)] = item
52+
else:
53+
self.minvals[self.IndexOfTop(stacknum)] = min(
54+
item, self.minvals[self.IndexOfTop(stacknum) - 1])
55+
self.array[self.IndexOfTop(stacknum)] = item
56+
57+
def Pop(self, stacknum):
58+
if self.IsEmpty(stacknum):
59+
raise Exception('Stack is empty')
60+
value = self.array[self.IndexOfTop(stacknum)]
61+
self.array[self.IndexOfTop(stacknum)] = 0
62+
self.sizes[stacknum] -= 1
63+
return value
64+
65+
def Peek(self, stacknum):
66+
if self.IsEmpty(stacknum):
67+
raise Exception('Stack is empty')
68+
return self.array[self.IndexOfTop(stacknum)]
69+
70+
def Min(self, stacknum):
71+
return self.minvals[self.IndexOfTop(stacknum)]
72+
73+
def IsEmpty(self, stacknum):
74+
return self.sizes[stacknum] == 0
75+
76+
def IsFull(self, stacknum):
77+
return self.sizes[stacknum] == self.stacksize
78+
79+
def IndexOfTop(self, stacknum):
80+
offset = stacknum * self.stacksize
81+
return offset + self.sizes[stacknum] - 1
82+
83+
#-------------------------------------------------------------------------------
84+
#Testing
85+
86+
class Node():
87+
def __init__(self, data=None, next=None):
88+
self.data, self.next = data, next
89+
90+
def __str__(self):
91+
string = str(self.data)
92+
if self.next:
93+
string += ',' + str(self.next)
94+
return string
95+
96+
class Test(unittest.TestCase):
97+
def test_min_stack(self):
98+
min_stack = MinStack()
99+
self.assertEqual(min_stack.min(), None)
100+
min_stack.push(7)
101+
self.assertEqual(min_stack.min(), 7)
102+
min_stack.push(6)
103+
min_stack.push(5)
104+
self.assertEqual(min_stack.min(), 5)
105+
min_stack.push(10)
106+
self.assertEqual(min_stack.min(), 5)
107+
self.assertEqual(min_stack.pop(), 10)
108+
self.assertEqual(min_stack.pop(), 5)
109+
self.assertEqual(min_stack.min(), 6)
110+
self.assertEqual(min_stack.pop(), 6)
111+
self.assertEqual(min_stack.pop(), 7)
112+
self.assertEqual(min_stack.min(), None)
113+
114+
if __name__ == "__main__":
115+
unittest.main()

CTCI/Chapter3/3.3-Stack_Of_Plates.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# CTCI 3.1
2+
# Three in One
3+
4+
import unittest
5+
6+
class MultiStack():
7+
def __init__(self, capacity):
8+
self.capacity = capacity
9+
self.stacks = []
10+
11+
def push(self, item):
12+
if len(self.stacks) and (len(self.stacks[-1]) < self.capacity):
13+
self.stacks[-1].append(item)
14+
else:
15+
self.stacks.append([item])
16+
17+
def pop(self):
18+
while len(self.stacks) and (len(self.stacks[-1]) == 0):
19+
self.stacks.pop()
20+
if len(self.stacks) == 0:
21+
return None
22+
item = self.stacks[-1].pop()
23+
if len(self.stacks[-1]) == 0:
24+
self.stacks.pop()
25+
return item
26+
27+
def pop_at(self, stack_number):
28+
if (stack_number < 0) or (len(self.stacks) <= stack_number):
29+
return None
30+
if len(self.stacks[stack_number]) == 0:
31+
return None
32+
return self.stacks[stack_number].pop()
33+
34+
35+
#-------------------------------------------------------------------------------
36+
# CTCI Solution
37+
38+
39+
#-------------------------------------------------------------------------------
40+
#Testing
41+
42+
class Test(unittest.TestCase):
43+
def test_multi_stack(self):
44+
stack = MultiStack(3)
45+
stack.push(11)
46+
stack.push(22)
47+
stack.push(33)
48+
stack.push(44)
49+
stack.push(55)
50+
stack.push(66)
51+
stack.push(77)
52+
stack.push(88)
53+
self.assertEqual(stack.pop(), 88)
54+
self.assertEqual(stack.pop_at(1), 66)
55+
self.assertEqual(stack.pop_at(0), 33)
56+
self.assertEqual(stack.pop_at(1), 55)
57+
self.assertEqual(stack.pop_at(1), 44)
58+
self.assertEqual(stack.pop_at(1), None)
59+
stack.push(99)
60+
self.assertEqual(stack.pop(), 99)
61+
self.assertEqual(stack.pop(), 77)
62+
self.assertEqual(stack.pop(), 22)
63+
self.assertEqual(stack.pop(), 11)
64+
self.assertEqual(stack.pop(), None)
65+
66+
if __name__ == "__main__":
67+
unittest.main()

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,9 @@ Cracking the Coding Interview 6th Edition Python Solutions
119119
| 2.7| | Intersection | [Python](CTCI/Chapter2/2.7-Intersection.py) |
120120
| 2.8| | Loop Detection | [Python](CTCI/Chapter2/2.8-Loop_Detection.py) |
121121
| | | | |
122-
| 3.1| | Three in One | [Python](CTCI/Chapter2/3.1-Three_In_One.py) |
122+
| 3.1| | Three in One | [Python](CTCI/Chapter3/3.1-Three_In_One.py) |
123+
| 3.2| | Stack Min | [Python](CTCI/Chapter3/3.2-Stack_Min.py) |
124+
| 3.3| | Stack of Plates | [Python](CTCI/Chapter3/3.3-Stack_Of_Plates.py) |
123125

124126
---
125127

0 commit comments

Comments
 (0)