-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathdesign-circular-queue.py
167 lines (148 loc) · 4.72 KB
/
design-circular-queue.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# 622. Design Circular Queue
# 🟠 Medium
#
# https://leetcode.com/problems/design-circular-queue/
#
# Tags: Array - Linked List - Design - Queue
from __future__ import annotations
import timeit
# A doubly linked list node.
class DListNode:
def __init__(
self,
next: DListNode = None,
val: int = 0,
):
self.next = next
self.val = val
def __repr__(self):
return f"DListNode({self.val})"
# Create a data structure that complies with the given requirements.
#
# Runtime: 80 ms, faster than 82.83%
# Memory Usage: 14.7 MB, less than 21.40%
class MyCircularQueue:
def __init__(self, k: int):
self.max_size = k
self.current_size = 0
self.back = None
self.front = None
# Enqueue works in O(1) - returns False if there is no room for the
# new node.
def enQueue(self, value: int) -> bool:
if self.isFull():
return False
# Create a new node
node = DListNode(val=value)
if self.isEmpty():
# Create a node and link it to itself.
# Linking the node to itself simplifies inserting later.
self.front = node
else:
# Update the back pointers.
self.back.next = node
# Always link to back
self.back = node
# Always increase the size.
self.current_size += 1
return True
# Removes the element at the front in O(1) - returns false if the
# queue is empty.
def deQueue(self) -> bool:
if self.isEmpty():
return False
# Special case, this is the only element.
if self.current_size == 1:
self.current_size = 0
self.back = None
self.front = None
return True
# Get the next node from the front, it could be self.back.
self.front = self.front.next
self.current_size -= 1
return True
# Get the element at the front of the queue in O(1)
def Front(self) -> int:
if self.isEmpty():
return -1
return self.front.val
# Get the element at the back of the queue in O(1)
def Rear(self) -> int:
if self.isEmpty():
return -1
return self.back.val
# Check if the queue is empty in O(1)
def isEmpty(self) -> bool:
return self.current_size == 0
# Check if the queue is full in O(1)
def isFull(self) -> bool:
return self.current_size == self.max_size
# Your MyCircularQueue object will be instantiated and called as such:
# obj = MyCircularQueue(k)
# param_1 = obj.enQueue(value)
# param_2 = obj.deQueue()
# param_3 = obj.Front()
# param_4 = obj.Rear()
# param_5 = obj.isEmpty()
# param_6 = obj.isFull()pass
def test():
executors = [MyCircularQueue]
tests = [
[
[
"MyCircularQueue",
"enQueue",
"enQueue",
"enQueue",
"enQueue",
"Rear",
"isFull",
"deQueue",
"enQueue",
"Rear",
],
[[3], [1], [2], [3], [4], [], [], [], [4], []],
[None, True, True, True, False, 3, True, True, True, 4],
],
[
[
"MyCircularQueue",
"enQueue",
"enQueue",
"deQueue",
"enQueue",
"deQueue",
"enQueue",
"deQueue",
"enQueue",
"deQueue",
"Front",
],
[[2], [1], [2], [], [3], [], [3], [], [3], [], []],
[None, True, True, True, True, True, True, True, True, True, 3],
],
]
for executor in executors:
start = timeit.default_timer()
for _ in range(1):
for col, t in enumerate(tests):
# The capacity comes wrapped in an array, unwrap it.
sol = executor(t[1][0][0])
for i in range(1, len(t[0])):
call = t[0][i]
# Only the enqueue call takes arguments
if call == "enQueue":
result = getattr(sol, call)(t[1][i][0])
else:
result = getattr(sol, call)()
exp = t[2][i]
assert result == exp, (
f"\033[93m» {result} <> {exp}\033[91m for"
+ f" test {col} using \033[1m{executor.__name__}"
)
stop = timeit.default_timer()
used = str(round(stop - start, 5))
cols = "{0:20}{1:10}{2:10}"
res = cols.format(executor.__name__, used, "seconds")
print(f"\033[92m» {res}\033[0m")
test()