Python Algorithm Q26
Q26 Design Circular Deque
Q
Design your implementation of the circular double-ended queue (deque).
Implement the MyCircularDeque
class:
MyCircularDeque(int k)
Initializes the deque with a maximum size ofk
.boolean insertFront()
Adds an item at the front of Deque. Returns true if the operation is successful, or false otherwise.boolean insertLast()
Adds an item at the rear of Deque. Returns true if the operation is successful, or false otherwise.boolean deleteFront()
Deletes an item from the front of Deque. Returns true if the operation is successful, or false otherwise.boolean deleteLast()
Deletes an item from the rear of Deque. Returns true if the operation is successful, or false otherwise.int getFront()
Returns the front item from the Deque. Returns -1 if the deque is empty.int getRear()
Returns the last item from Deque. Returns -1 if the deque is empty.boolean isEmpty()
Returns true if the deque is empty, or false otherwise.boolean isFull()
Returns true if the deque is full, or false otherwise.
Sample Input
Input
[“MyCircularDeque”, “insertLast”, “insertLast”, “insertFront”, “insertFront”, “getRear”, “isFull”, “deleteLast”, “insertFront”, “getFront”]
[[3], [1], [2], [3], [4], [], [], [], [4], []]
Output
[null, true, true, true, false, 2, true, true, true, 4]
Explanation
MyCircularDeque myCircularDeque = new MyCircularDeque(3);
myCircularDeque.insertLast(1); // return True
myCircularDeque.insertLast(2); // return True
myCircularDeque.insertFront(3); // return True
myCircularDeque.insertFront(4); // return False, the queue is full.
myCircularDeque.getRear(); // return 2
myCircularDeque.isFull(); // return True
myCircularDeque.deleteLast(); // return True
myCircularDeque.insertFront(4); // return True
myCircularDeque.getFront(); // return 4
Constraints
- 1 <=
k
<= 1000 - 0 <=
value
<= 1000 - At most
2000
calls will be made toinsertFront
,insertLast
,deleteFront
,deleteLast
,getFront
,getRear
,isEmpty
,isFull
.
1. My Solution =~ Given Solution
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
class Node():
def __init__(self, val = None, prev = None, next = None): #값, 전 주소, 다음 주소
self.val = val
self.prev = prev
self.next = next
class MyCircularDeque:
def __init__(self, k: int):
self.head, self.tail = Node(), Node()
self.head.next = self.tail
self.tail.prev = self.head
self.maxlen = k
self.cnt = 0
def _add(self, node: Node(), new_node: Node()):
a = node.next
node.next = new_node
new_node.prev, new_node.next = node, a
a.prev = new_node
def _del(self, node: Node()):
prev, next = node.prev, node.next
node.next.prev = prev
node.prev.next = next
def insertFront(self, value: int) -> bool:
if self.cnt == self.maxlen:
return False
else:
self.cnt += 1
self._add(self.head,Node(value))
return True
def insertLast(self, value: int) -> bool:
if self.cnt == self.maxlen:
return False
else:
self.cnt += 1
self._add(self.tail.prev, Node(value))
return True
def deleteFront(self) -> bool:
if self.cnt == 0:
return False
else:
self.cnt -= 1
self._del(self.head.next)
return True
def deleteLast(self) -> bool:
if self.cnt == 0:
return False
else:
self.cnt -= 1
self._del(self.tail.prev)
return True
def getFront(self) -> int:
if self.isEmpty():
return -1
else:
return self.head.next.val
def getRear(self) -> int:
if self.isEmpty():
return -1
else:
return self.tail.prev.val
def isEmpty(self) -> bool:
if self.cnt == 0:
return True
else:
return False
def isFull(self) -> bool:
if self.cnt == self.maxlen:
return True
else:
return False
In this problem, the term “circular” is not that important. Just performing the functions provided is our goal. Let’s focus on the variables of init function.
- self.head, self.tail = Node(), Node() : create main head and tail node.
- self.head.next, self.tail.prev = self.tail, self.head : connecting head and tail.
- self.maxlen = k : saving max length.
- self.cnt = 0 : for counting.
The concept of this type is “INSERT” between head and tail. At ANY CASE, head and tail do not change. They are just sign for the start and the end. Therefore, adding nodes to the deque is done by INSERTION. That’s why I define _add and _del function just like insertion. Understanding this concept, the problem is not hard at all. You can easily follow my codes without any description.
*tips : adding underscore(“_”) to the function name is the promise that those functions will used only inside the class(object).
Overall Review
At first, this question looks so intricated. Implementing deque with double-linked list… Looks not that easy. Even I considered making all nodes at initialization then pushing values afterward… However devising to use fixed HEAD and TAIL is really brilliant. Just let them exist both sides, the question easily solved!!