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