@@ -32,22 +32,25 @@ class LinkedList:
32
32
def __init__ (self , * numbers : int ):
33
33
self .head = None
34
34
self .tail = None
35
+ self .size = 0
35
36
for num in numbers :
36
37
self .append_to_tail (num )
37
38
38
39
def append_to_tail (self , d : int ) -> None :
39
40
if self .head is None :
40
41
self .head = Node (d )
41
42
self .tail = self .head
42
- return
43
- end = Node (d )
44
- self .tail .next = end
45
- self .tail = end
43
+ else :
44
+ end = Node (d )
45
+ self .tail .next = end
46
+ self .tail = end
47
+ self .size += 1
46
48
47
49
def append_to_head (self , d : int ) -> None :
48
50
new_head = Node (d )
49
51
new_head .next = self .head
50
52
self .head = new_head
53
+ self .size += 1
51
54
52
55
def __repr__ (self ):
53
56
return self .__str__ ()
@@ -84,79 +87,39 @@ def kth_to_last(ll: LinkedList, k: int) -> Node:
84
87
Going to reverse the linked list and then
85
88
count k steps.
86
89
Runtime: O(N)
87
- Space Complexity: O(N )
90
+ Space Complexity: O(1 )
88
91
:param ll: a linked list
89
- :param k: an integer where k >= 0
92
+ :param k:
93
+ an integer where k > 0 and k < ll size
90
94
:return:
91
95
kth to last Node from the linked list
92
96
or None
93
97
"""
94
- if k <= 0 :
95
- return None
96
- # build reversed linked list
97
- reversed_ll = LinkedList (ll .head .data )
98
- n = ll .head .next
99
- while n is not None :
100
- reversed_ll .append_to_head (n .data )
101
- n = n .next
102
- # go k steps
98
+ if k <= 0 or k > ll .size :
99
+ raise IndexError ('list index out of range' )
100
+ # go size - k steps
101
+ n = ll .head
103
102
i = 1
104
- n = reversed_ll .head
105
- while n is not None and i < k :
103
+ while n is not None and i <= ll .size - k :
106
104
n = n .next
107
105
i += 1
108
106
return n
109
107
110
108
111
109
class TestKthToLast (unittest .TestCase ):
112
110
113
- def setUp (self ):
114
- self .test_cases = [
115
- (
116
- LinkedList (1 , 2 , 3 , 4 , 5 , 6 ),
117
- 2 ,
118
- Node (5 )
119
- ),
120
- (
121
- LinkedList (1 , 2 , 3 , 4 , 5 , 6 ),
122
- 1 ,
123
- Node (6 )
124
- ),
125
- (
126
- LinkedList (1 , 2 , 3 , 4 , 5 , 6 ),
127
- 4 ,
128
- Node (3 )
129
- ),
130
- (
131
- LinkedList (1 , 2 , 3 , 4 , 5 , 6 ),
132
- 5 ,
133
- Node (2 )
134
- ),
135
- (
136
- LinkedList (1 , 2 , 3 , 4 , 5 , 6 ),
137
- 6 ,
138
- Node (1 )
139
- ),
140
- (
141
- LinkedList (1 , 2 , 3 , 4 , 5 , 6 ),
142
- 7 ,
143
- None
144
- ),
145
- (
146
- LinkedList (1 ),
147
- 1 ,
148
- Node (1 )
149
- ),
150
- (
151
- LinkedList (5 ),
152
- 0 ,
153
- None
154
- ),
155
- ]
156
-
157
111
def test_kth_to_last (self ):
158
- for ll , k , expected in self .test_cases :
159
- self .assertEqual (kth_to_last (ll , k ), expected , msg = (ll , expected ))
112
+ l = list (range (1 , 6 ))
113
+ ll = LinkedList (* l )
114
+ for k in range (1 , len (l )):
115
+ self .assertEqual (kth_to_last (ll , k ), Node (l [- k ]), msg = (ll , l [- k ]))
116
+
117
+ def test_kth_to_last_index_error (self ):
118
+ k_values = [- 1 , 7 , 0 ]
119
+ ll = LinkedList (1 , 2 , 3 )
120
+ for k in k_values :
121
+ with self .assertRaises (IndexError , msg = (ll , k )):
122
+ kth_to_last (ll , k )
160
123
161
124
162
125
if __name__ == '__main__' :
0 commit comments