Skip to content

Commit a5e8ce1

Browse files
committed
add 2.1_remove_duplicates_from_linked_list.py
1 parent 6b13132 commit a5e8ce1

9 files changed

+128
-132
lines changed

Cracking_the_coding_interview/2.1_remove_duplicates_from_linked_list.py

-131
This file was deleted.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
'''Question:
2+
Write code to remove duplicates from an unsorted linked list. FOLLOW UP
3+
How would you solve this problem if a temporary buffer is not allowed?
4+
5+
clarification:
6+
- singly linked list? yes
7+
- will there be circles? no
8+
- can I assume the linked list only contains integer data? yes
9+
- if thare are dups at position x and x+n, remove the one at x+n
10+
- the order should be reserved
11+
- what is a temporary buffer? it means even hash table cannot be used
12+
- return head
13+
'''
14+
15+
import unittest
16+
from test_utils import UnitTestBase
17+
from data_structure import Node, LinkedList as LL
18+
19+
# Solution: use hash table
20+
# Time: O(n)
21+
# Space: O(n)
22+
def remove_dups_1(ll):
23+
cur = ll.head
24+
if cur == None:
25+
return ll
26+
27+
keys = set([cur.data])
28+
while cur.next != None:
29+
key = cur.next.data
30+
if key not in keys:
31+
keys.add(key)
32+
cur = cur.next
33+
else:
34+
cur.next = cur.next.next
35+
36+
return ll
37+
38+
# Solution: no temporaty buffer
39+
# Time: O(n*n)
40+
# Space: O(1)
41+
def remove_dups_2(ll):
42+
anchor = ll.head
43+
while anchor != None:
44+
cur, key = anchor, anchor.data
45+
46+
while cur.next != None:
47+
if cur.next.data != key:
48+
cur = cur.next
49+
else:
50+
cur.next = cur.next.next
51+
52+
anchor = anchor.next
53+
54+
return ll
55+
56+
# Solution: no temporaty buffer. recursion
57+
# Time: O(n*n)
58+
# Space: O(1) - tail recursion
59+
def remove_dups_3(ll):
60+
remove_dups_3_helper(ll.head)
61+
return ll
62+
63+
def remove_dups_3_helper(anchor):
64+
if anchor == None:
65+
return
66+
67+
cur, key = anchor, anchor.data
68+
69+
while cur.next != None:
70+
if cur.next.data != key:
71+
cur = cur.next
72+
else:
73+
cur.next = cur.next.next
74+
75+
remove_dups_3_helper(anchor.next)
76+
77+
class Test(UnitTestBase, unittest.TestCase):
78+
def data_provider(self):
79+
return [
80+
(LL(), LL()),
81+
(LL([1]), LL([1])),
82+
(LL([1, 2, 3]), LL([1, 2, 3])),
83+
(LL([1, 1]), LL([1])),
84+
(LL([4, 8, 2, 4]), LL([4, 8, 2])),
85+
(LL([4, 2, 2, 4]), LL([4, 2])),
86+
(LL([1, 4, 6, 8, 6, 2, 1]), LL([1, 4, 6, 8, 2])),
87+
(LL([4, 2, 3, 4, 8, 6, 6, 2]), LL([4, 2, 3, 8, 6])),
88+
]
89+
90+
def func_provider(self):
91+
return [
92+
remove_dups_1,
93+
remove_dups_2,
94+
remove_dups_3,
95+
]
96+
97+
def func_eval(self, func, args):
98+
return func(args)
99+
100+
if __name__ == '__main__':
101+
unittest.main()
Binary file not shown.
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
class Node():
2+
def __init__(self, data, next = None):
3+
self.data = data
4+
self.next = next
5+
def __str__(self):
6+
return str(self.data)
7+
8+
class LinkedList():
9+
def __init__(self, lst = []):
10+
cur = None
11+
for i in range(len(lst) - 1, -1, -1):
12+
data = lst[i]
13+
n = Node(data, cur)
14+
cur = n
15+
self.head = cur
16+
17+
def __str__(self):
18+
res = []
19+
cur = self.head
20+
while cur != None:
21+
res.append(cur.data)
22+
cur = cur.next
23+
return str(res)

Cracking_the_coding_interview/v6/test_utils.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def single_test(self, func, data):
2626

2727
def expect(self, result, func, data):
2828
expected = data[1]
29-
self.assertEqual(result, expected, self.err_msg(func, data))
29+
self.assertEqual(str(result), str(expected), self.err_msg(func, data))
3030

3131
def err_msg(self, func, data):
3232
return 'Failed \'' + func.__name__ + '\'. args & expected: ' + str(data)
212 Bytes
Binary file not shown.

common_mistakes.txt

+3
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,6 @@ example: 1.5 one_away_1 at Hot Spot 1 & 2
2626
12. 'header'.join(['a', 'b'])
2727
- this does not produce: 'headerab', instead it will output 'aheaderb'
2828
- the right way to do it is: 'header' + ''.join(['a', 'b'])
29+
13. while len(lst) > 0:
30+
data = lst.pop()
31+
this will have side effect on the list. not recommended for looping a list

0 commit comments

Comments
 (0)