Skip to content

Commit c7e80f0

Browse files
committed
LeetCode 203. Remove Linked List Elements
1 parent b9861c3 commit c7e80f0

File tree

2 files changed

+120
-4
lines changed

2 files changed

+120
-4
lines changed

README.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,12 @@ Solutions to LeetCode problems. The first column links to the problem in LeetCod
110110
| [200. Number of Islands][lc200] | 🟠 Medium | [![python](res/py.png)][lc200py] |
111111
| [202. Happy Number][lc202] | 🟢 Easy | [![python](res/py.png)][lc202py] |
112112
| [203. Remove Linked List Elements][lc203] | 🟢 Easy | [![python](res/py.png)][lc203py] |
113-
| [205. Isomorphic Strings][lc205] | 🟢 Easy | [![python](res/py.png)](leetcode/isomorphic-strings.py) |
114-
| [206. Reverse Linked List][lc206] | 🟢 Easy | [![python](res/py.png)](leetcode/reverse-linked-list.py) |
113+
| [205. Isomorphic Strings][lc205] | 🟢 Easy | [![python](res/py.png)][lc205py] |
114+
| [206. Reverse Linked List][lc206] | 🟢 Easy | [![python](res/py.png)][lc206py] |
115115
| [207. Course Schedule][lc207] | 🟠 Medium | [![python](res/py.png)][lc207py] |
116-
| [208. Implement Trie (Prefix Tree)][lc208] | 🟠 Medium | [![python](res/py.png)](leetcode/implement-trie-prefix-tree.py) |
116+
| [208. Implement Trie (Prefix Tree)][lc208] | 🟠 Medium | [![python](res/py.png)][lc208py] |
117117
| [210. Course Schedule II][lc210] | 🟠 Medium | [![python](res/py.png)][lc210py] |
118-
| [211. Design Add and Search Words Data Structure][lc211] | 🟠 Medium | [![python](res/py.png)](leetcode/design-add-and-search-words-data-structure.py) |
118+
| [211. Design Add and Search Words Data Structure][lc211] | 🟠 Medium | [![python](res/py.png)][lc211py] |
119119
| [213. House Robber II][lc213] | 🟠 Medium | [![python](res/py.png)][lc213py] |
120120
| [215. Kth Largest Element in an Array][lc215] | 🟠 Medium | [![python](res/py.png)][lc215py] |
121121
| [217. Contains Duplicate][lc217] | 🟢 Easy | [![python](res/py.png)][lc217py] |
@@ -469,13 +469,17 @@ Solutions to LeetCode problems. The first column links to the problem in LeetCod
469469
[lc203]: https://leetcode.com/problems/remove-linked-list-elements/
470470
[lc203py]: leetcode/remove-linked-list-elements.py
471471
[lc205]: https://leetcode.com/problems/isomorphic-strings/
472+
[lc205py]: leetcode/isomorphic-strings.py
472473
[lc206]: https://leetcode.com/problems/reverse-linked-list/
474+
[lc206py]: leetcode/reverse-linked-list.py
473475
[lc207]: https://leetcode.com/problems/course-schedule/
474476
[lc207py]: leetcode/course-schedule.py
475477
[lc208]: https://leetcode.com/problems/implement-trie-prefix-tree/
478+
[lc208py]: leetcode/implement-trie-prefix-tree.py
476479
[lc210]: https://leetcode.com/problems/course-schedule-ii/
477480
[lc210py]: leetcode/course-schedule-ii.py
478481
[lc211]: https://leetcode.com/problems/design-add-and-search-words-data-structure/
482+
[lc211py]: leetcode/design-add-and-search-words-data-structure.py
479483
[lc213]: https://leetcode.com/problems/house-robber-ii/
480484
[lc213py]: leetcode/house-robber-ii.py
481485
[lc215]: https://leetcode.com/problems/kth-largest-element-in-an-array/
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# 203. Remove Linked List Elements
2+
# 🟢 Easy
3+
#
4+
# https://leetcode.com/problems/remove-linked-list-elements/
5+
#
6+
# Tags: Linked List - Recursion
7+
8+
import timeit
9+
from typing import Optional
10+
11+
from data import LinkedList, ListNode
12+
13+
14+
# Start by eliminating the value from the list head by skipping the
15+
# pointer to head.next, if after this step we still have a head, travel
16+
# through the list nodes checking the value of the next node, if it
17+
# matches the search value, delete that node updating the linked list
18+
# pointers.
19+
#
20+
# Time complexity: O(n) - We visit each node once.
21+
# Space complexity; O(1) - We only keep pointers in memory.
22+
#
23+
# Runtime: 126 ms, faster than 54.5%
24+
# Memory Usage: 17.8 MB, less than 38.78%
25+
class Solution:
26+
def removeElements(
27+
self, head: Optional[ListNode], val: int
28+
) -> Optional[ListNode]:
29+
# Remove val from the head.
30+
while head:
31+
if head.val == val:
32+
dup = head
33+
head = head.next
34+
del dup
35+
else:
36+
break
37+
if not head:
38+
return None
39+
# Remove val from the middle/end.
40+
current = head
41+
while current.next:
42+
next = current.next
43+
# Skip the value or move the pointer.
44+
if next.val == val:
45+
current.next = next.next
46+
del next
47+
else:
48+
current = current.next
49+
return head
50+
51+
52+
# Since the head could be null or it could contain the value we want to
53+
# remove from the list, use a dummy node as the temporary head, then we
54+
# can treat the head as any other node and iterate over the nodes
55+
# removing duplicate values. Once done, we return dummy.next.
56+
#
57+
# Time complexity: O(n) - We visit each node once.
58+
# Space complexity; O(1) - We only keep pointers in memory.
59+
#
60+
# Runtime: 149 ms, faster than 30.30%
61+
# Memory Usage: 17.8 MB, less than 38.78%
62+
class Dummy:
63+
def removeElements(
64+
self, head: Optional[ListNode], val: int
65+
) -> Optional[ListNode]:
66+
# Create a dummy node that points to the head.
67+
dummy = ListNode(next=head)
68+
current = dummy
69+
while current.next:
70+
# If we need to remove the next node, do it.
71+
if current.next.val == val:
72+
next = current.next
73+
current.next = next.next
74+
del next
75+
# If we don't need to remove the next node, move the pointer.
76+
else:
77+
current = current.next
78+
# Return the head of the result list, it could be null.
79+
return dummy.next
80+
81+
82+
def test():
83+
executors = [
84+
Solution,
85+
Dummy,
86+
]
87+
tests = [
88+
[[], 1, []],
89+
[[7, 7, 7, 7], 7, []],
90+
[[1, 2, 6, 3, 4, 5, 6], 6, [1, 2, 3, 4, 5]],
91+
]
92+
for executor in executors:
93+
start = timeit.default_timer()
94+
for _ in range(1):
95+
for col, t in enumerate(tests):
96+
sol = executor()
97+
head = LinkedList.fromList(t[0]).getHead()
98+
result_head = sol.removeElements(head, t[1])
99+
result = LinkedList(result_head).toList()
100+
exp = t[2]
101+
assert result == exp, (
102+
f"\033[93m» {result} <> {exp}\033[91m for"
103+
+ f" test {col} using \033[1m{executor.__name__}"
104+
)
105+
stop = timeit.default_timer()
106+
used = str(round(stop - start, 5))
107+
cols = "{0:20}{1:10}{2:10}"
108+
res = cols.format(executor.__name__, used, "seconds")
109+
print(f"\033[92m» {res}\033[0m")
110+
111+
112+
test()

0 commit comments

Comments
 (0)