Skip to content

Commit 5c8d9ef

Browse files
committed
miguel soln to kth to last 2.2
1 parent 8ad3fff commit 5c8d9ef

File tree

1 file changed

+163
-0
lines changed

1 file changed

+163
-0
lines changed
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
"""
2+
Python version 3.7.0
3+
2.2 - Return Kth to Last
4+
Implement an algorithm to find the kth
5+
to last element of a singly linked list
6+
Example:
7+
input: ll = a -> b -> c -> d -> e -> f
8+
k = 3
9+
output: d because d is 3rd to last
10+
"""
11+
import unittest
12+
13+
14+
class Node:
15+
def __init__(self, d: int):
16+
self.data = d
17+
self.next = None
18+
19+
def __repr__(self):
20+
return self.__str__()
21+
22+
def __str__(self):
23+
return '<Node Value: {}>'.format(self.data)
24+
25+
def __eq__(self, other: object):
26+
if not isinstance(other, Node):
27+
return NotImplemented
28+
return self.data == other.data
29+
30+
31+
class LinkedList:
32+
def __init__(self, *numbers: int):
33+
self.head = None
34+
self.tail = None
35+
for num in numbers:
36+
self.append_to_tail(num)
37+
38+
def append_to_tail(self, d: int) -> None:
39+
if self.head is None:
40+
self.head = Node(d)
41+
self.tail = self.head
42+
return
43+
end = Node(d)
44+
self.tail.next = end
45+
self.tail = end
46+
47+
def append_to_head(self, d: int) -> None:
48+
new_head = Node(d)
49+
new_head.next = self.head
50+
self.head = new_head
51+
52+
def __repr__(self):
53+
return self.__str__()
54+
55+
def __str__(self):
56+
if self.head is None:
57+
return '<empty>'
58+
ll = []
59+
n = self.head
60+
while n.next is not None:
61+
ll.append('{} -> '.format(n.data))
62+
n = n.next
63+
ll.append(str(n.data))
64+
return ''.join(ll)
65+
66+
def __eq__(self, other: object):
67+
if not isinstance(other, LinkedList):
68+
return NotImplemented
69+
a = self.head
70+
b = other.head
71+
while a is not None and b is not None:
72+
if a.data != b.data:
73+
return False
74+
# otherwise, advance both pointers
75+
a = a.next
76+
b = b.next
77+
return a is None and b is None
78+
79+
80+
def kth_to_last(ll: LinkedList, k: int) -> Node:
81+
"""
82+
kth_to_last will return the kth to last node
83+
from the input linked list.
84+
Going to reverse the linked list and then
85+
count k steps.
86+
Runtime: O(N)
87+
Space Complexity: O(N)
88+
:param ll: a linked list
89+
:param k: an integer where k >= 0
90+
:return:
91+
kth to last Node from the linked list
92+
or None
93+
"""
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
103+
i = 1
104+
n = reversed_ll.head
105+
while n is not None and i < k:
106+
n = n.next
107+
i += 1
108+
return n
109+
110+
111+
class TestKthToLast(unittest.TestCase):
112+
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+
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))
160+
161+
162+
if __name__ == '__main__':
163+
unittest.main()

0 commit comments

Comments
 (0)