-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdeque.py
131 lines (112 loc) · 3.53 KB
/
deque.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
#
# https://wiki.python.org/moin/TimeComplexity
#
# using a index_map {} for O(1) getter and setter
# would result in appendLeft and PopLeft being O(N)
#
from typing import Optional
class Node:
def __init__(self, val: any = None) -> None:
self.val = val
self.prev = None
self.next = None
class Deque:
def __init__(self, elements: Optional[list[any]] = []) -> None:
"""Time complexity: O(N)."""
self.head = None
self.tail = None
self.length = 0
for e in elements:
self.append(e)
def __len__(self):
"""Time complexity: O(1)."""
return self.length
def __iter__(self):
"""Time complexity: O(N)."""
node = self.head
while node:
yield node.val
node = node.next
def __getitem__(self, index: int) -> any:
"""Time complexity: O(N)."""
_index = index if index >= 0 else self.length + index
if not 0 <= _index < self.length:
raise IndexError("index out of range")
node = self.head
for _ in range(_index):
node = node.next
return node.val
def __setitem__(self, index: int, value: any) -> None:
"""Time complexity: O(N)."""
_index = index if index >= 0 else self.length + index
if not 0 <= _index < self.length:
raise IndexError("index out of range")
node = self.head
for _ in range(_index):
node = node.next
node.val = value
def __bool__(self) -> bool:
return not self.is_empty()
def is_empty(self):
"""Time complexity: O(1)."""
return self.length == 0
def append_left(self, val: any) -> None:
"""Time complexity: O(1)."""
node = Node(val)
if self.is_empty():
self.head = self.tail = node
else:
node.next = self.head
self.head.prev = node
self.head = node
self.length += 1
def append(self, val: any) -> None:
"""Time complexity: O(1)."""
node = Node(val)
if self.is_empty():
self.head = self.tail = node
else:
node.prev = self.tail
self.tail.next = node
self.tail = node
self.length += 1
def pop_left(self):
"""Time complexity: O(1)."""
if self.is_empty():
raise IndexError("not able to pop from empty deque")
val = self.head.val
if self.head == self.tail:
self.head = self.tail = None
else:
self.head = self.head.next
self.head.prev = None
self.length -= 1
return val
def pop(self):
"""Time complexity: O(1)."""
if self.is_empty():
raise IndexError("not able to pop from empty deque")
val = self.tail.val
if self.head == self.tail:
self.head = self.tail = None
else:
self.tail = self.tail.prev
self.tail.next = None
self.length -= 1
return val
def remove(self, val: any) -> bool:
"""Time complexity: O(N)."""
node = self.head
while node:
if node.val == val:
if node.prev is None:
self.pop_left()
elif node.next is None:
self.pop()
else:
node.prev.next = node.next
node.next.prev = node.prev
self.length -= 1
return True
node = node.next
return False