Skip to content

Commit cfd42e9

Browse files
committed
miguel soln to 2.1 remove dups
1 parent 8ad3fff commit cfd42e9

File tree

1 file changed

+147
-0
lines changed

1 file changed

+147
-0
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
"""
2+
Python version 3.7.0
3+
2.1 - Remove Dups
4+
Write code to remove duplicates
5+
from an unsorted linked list.
6+
How would you solve this if a temporary
7+
buffer is not allowed?
8+
"""
9+
import unittest
10+
from typing import List
11+
12+
13+
class Node:
14+
def __init__(self, d: int):
15+
self.data = d
16+
self.next = None
17+
18+
19+
class LinkedList:
20+
def __init__(self):
21+
self.head = None
22+
23+
def append_to_tail(self, d: int) -> None:
24+
if self.head is None:
25+
self.head = Node(d)
26+
return
27+
end = Node(d)
28+
n = self.head
29+
while n.next is not None:
30+
n = n.next
31+
n.next = end
32+
33+
def append_to_head(self, d: int) -> None:
34+
new_head = Node(d)
35+
new_head.next = self.head
36+
self.head = new_head
37+
38+
def __repr__(self):
39+
return self.__str__()
40+
41+
def __str__(self):
42+
if self.head is None:
43+
return '<empty'
44+
ll = []
45+
n = self.head
46+
while n.next is not None:
47+
ll.append('{} -> '.format(n.data))
48+
n = n.next
49+
ll.append(str(n.data))
50+
return ''.join(ll)
51+
52+
def __eq__(self, other):
53+
a = self.head
54+
b = other.head
55+
while a is not None and b is not None:
56+
if a.data != b.data:
57+
return False
58+
# otherwise, advance both pointers
59+
a = a.next
60+
b = b.next
61+
return a is None and b is None
62+
63+
64+
def build_linked_list(numbers: List[int]) -> LinkedList:
65+
ll = LinkedList()
66+
for num in numbers:
67+
ll.append_to_tail(num)
68+
return ll
69+
70+
71+
def remove_dups(ll: LinkedList) -> LinkedList:
72+
"""
73+
remove_dups will remove duplicates from the
74+
input linked list ll. No temporary buffer
75+
used.
76+
Runtime: O(N^2)
77+
Space Complexity: O(1)
78+
:param ll: a linked list
79+
:return: a linked list without duplicates
80+
"""
81+
n = ll.head
82+
while n.next is not None:
83+
curr_data = n.data
84+
m = n.next
85+
prev = n
86+
# search for duplicates from n + 1 to the
87+
# end of the linked list
88+
while m is not None:
89+
if m.data == curr_data:
90+
# re-arrange pointers to omit
91+
# the duplicate
92+
prev.next = m.next
93+
m = prev.next
94+
else:
95+
# otherwise, advance m and prev pointers
96+
prev = m
97+
m = m.next
98+
n = n.next
99+
# if the following is true, this
100+
# means we are at the end of the ll
101+
# and we removed a value at the end
102+
if n is None:
103+
break
104+
return ll
105+
106+
107+
class TestRemoveDups(unittest.TestCase):
108+
109+
def setUp(self):
110+
self.test_cases = [
111+
(
112+
build_linked_list([1, 2, 3, 3, 5]),
113+
build_linked_list([1, 2, 3, 5])
114+
),
115+
(
116+
build_linked_list([1, 2, 3, 3]),
117+
build_linked_list([1, 2, 3])
118+
),
119+
(
120+
build_linked_list([1, 2, 2]),
121+
build_linked_list([1, 2])
122+
),
123+
(
124+
build_linked_list([1]),
125+
build_linked_list([1])
126+
),
127+
(
128+
build_linked_list([1, 1]),
129+
build_linked_list([1])
130+
),
131+
(
132+
build_linked_list([2, 2, 2, 2, 2, 2]),
133+
build_linked_list([2])
134+
),
135+
(
136+
build_linked_list([1, 1, 3, 4, 5, 5, 6, 7]),
137+
build_linked_list([1, 3, 4, 5, 6, 7])
138+
),
139+
]
140+
141+
def test_remove_dups(self):
142+
for ll, expected in self.test_cases:
143+
self.assertEqual(remove_dups(ll), expected)
144+
145+
146+
if __name__ == '__main__':
147+
unittest.main()

0 commit comments

Comments
 (0)