1
- # This is an input class. Do not edit.
2
- class Node :
3
- def __init__ (self , value ):
4
- self .value = value
5
- self .prev = None
6
- self .next = None
7
-
8
-
9
- # Code is OK but test cases are failing. DOn't know why
10
1
class DoublyLinkedList :
11
2
def __init__ (self ):
12
3
self .head = None
13
4
self .tail = None
14
5
6
+ # O(1) time | O(1) space
15
7
def setHead (self , node ):
16
8
if self .head is None :
17
9
self .head = node
18
10
self .tail = node
19
11
return
20
- self .insertBefore (self .head , node )
12
+ self .insertBefore (self .head , node ) # corner case -- setting new head
21
13
14
+ # O(1) time | O(1) space
22
15
def setTail (self , node ):
23
16
if self .tail is None :
24
17
self .setHead (node )
25
18
return
26
19
self .insertAfter (self .tail , node )
27
20
21
+ # O(1) time | O(1) space
28
22
def insertBefore (self , node , nodeToInsert ):
23
+ # edge case
29
24
if nodeToInsert == self .head and nodeToInsert == self .tail :
30
25
return
31
- self .remove (nodeToInsert )
26
+ self .remove (nodeToInsert ) # if the node exists in the linked list we will remove it. This step can be skipped
32
27
nodeToInsert .prev = node .prev
33
28
nodeToInsert .next = node
34
- if not node .prev :
29
+ if node .prev is None :
35
30
self .head = nodeToInsert
36
31
else :
37
32
node .prev .next = nodeToInsert
38
33
node .prev = nodeToInsert
39
34
35
+ # O(1) time | O(1) space
40
36
def insertAfter (self , node , nodeToInsert ):
41
37
if nodeToInsert == self .head and nodeToInsert == self .tail :
42
38
return
43
- self .remove (nodeToInsert )
39
+ self .remove (nodeToInsert ) # if the node exists in the linked list we will remove it. This step can be skipped
44
40
nodeToInsert .prev = node
45
41
nodeToInsert .next = node .next
46
- if not node .next :
42
+ if node .next == None :
47
43
self .tail = nodeToInsert
48
44
else :
49
45
node .next .prev = nodeToInsert
50
46
node .next = nodeToInsert
51
47
48
+ # O(Position) time | O(1) space
52
49
def insertAtPosition (self , position , nodeToInsert ):
53
50
if position == 1 :
54
51
self .setHead (nodeToInsert )
55
52
return
56
53
node = self .head
57
- currPos = 1
58
- while node and currPos != position :
54
+ currentPosition = 1
55
+ while node is not None and currentPosition != position :
59
56
node = node .next
60
- currPos += 1
61
- if node :
62
- self .insertBefore (nodeToInsert )
57
+ currentPosition += 1
58
+ if node is not None :
59
+ self .insertBefore (node , nodeToInsert )
63
60
else :
64
61
self .setTail (nodeToInsert )
65
62
63
+ # O(n) time | O(1) space
66
64
def removeNodesWithValue (self , value ):
67
65
node = self .head
68
- while node :
66
+ while node is not None :
67
+ # we need this temp variable because we are losing node.next in removeNodeBindinnodegs()
69
68
nodeToRemove = node
70
69
node = node .next
71
70
if nodeToRemove .value == value :
72
71
self .remove (nodeToRemove )
73
72
73
+ # O(1) time | O(1) space
74
74
def remove (self , node ):
75
- if node == self .head :
75
+ if ( node == self .head ) :
76
76
self .head = self .head .next
77
- if node == self .tail :
77
+ if ( node == self .tail ) :
78
78
self .tail = self .tail .prev
79
+ # checks if we are removing head or tail and updating new head or tail
79
80
self .removeNodeBindings (node )
80
81
82
+ # O(n) time | O(1) space
81
83
def containsNodeWithValue (self , value ):
82
84
node = self .head
83
- while node and node .value != value :
85
+ while node is not None and node .value != value :
84
86
node = node .next
85
87
return node is not None
86
88
87
89
def removeNodeBindings (self , node ):
88
- if node .prev :
90
+ if node .prev is not None :
89
91
node .prev .next = node .next
90
- if node .next :
92
+ if node .next is not None :
91
93
node .next .prev = node .prev
92
94
node .prev = None
93
95
node .next = None
96
+
97
+
98
+ class node :
99
+ def __init__ (self , value ):
100
+ self .prev = None
101
+ self .next = None
102
+ self .value = value
0 commit comments