Skip to content

Commit 02c92b7

Browse files
Add 'Remove Nth Node From End of List'
1 parent 1ed081b commit 02c92b7

File tree

3 files changed

+116
-0
lines changed

3 files changed

+116
-0
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ A collection of LeetCode solutions
3434

3535
[Product of Array Except Self](./src/product_of_array_except_self.py)
3636

37+
[Remove Nth Node From End of List](./src/remove_nth_node_from_end_of_list.py)
38+
3739
[Reverse Linked List](./src/reverse_linked_list.py)
3840

3941
[Same Tree](./src/same_tree.py)
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
"""
2+
19. Remove Nth Node From End of List
3+
4+
https://leetcode.com/problems/remove-nth-node-from-end-of-list
5+
6+
NOTES
7+
* To remove the nth node from the end of a linked list, we can use a two
8+
pointers technique. One pointer (p1) starts at the head, while another
9+
pointer (p2) starts n nodes ahead of p1. When p2 reaches the end, p1 will
10+
be at the nth node.
11+
12+
Example (where ○ represents null):
13+
14+
1 2 3 4 5
15+
○ → ● → ● → ● → ● → ● → ○ n = 2
16+
↑ ↑
17+
p1,p2
18+
prev
19+
20+
Start by instantiating a head sentinel node. This allows us to more
21+
easily handle the case where n is equal to the length of the list.
22+
23+
Next, advance p2 by n nodes:
24+
25+
1 2 3 4 5
26+
○ → ● → ● → ● → ● → ● → ○ n = 2
27+
↑ ↑ ↑
28+
p1 p2
29+
prev
30+
31+
Next, advance p1 and p2 together, maintaining prev as the node before p1,
32+
until p2 reaches the end of the list:
33+
34+
1 2 3 4 5
35+
○ → ● → ● → ● → ● → ● → ○ n = 2
36+
↑ ↑ ↑
37+
p1 p2
38+
prev
39+
40+
Finally, remove the nth node (p1) by connecting prev to p1.next:
41+
42+
1 2 3 5
43+
○ → ● → ● → ● → ● → ○ n = 2
44+
"""
45+
46+
from src.classes import ListNode
47+
48+
49+
class Solution:
50+
def removeNthFromEnd(self, head: ListNode | None, n: int) -> ListNode | None:
51+
if not head:
52+
return None
53+
54+
# Use a head sentinel node to handle removing the first node.
55+
prehead = ListNode(-1)
56+
prehead.next = head
57+
prev = prehead
58+
59+
p1, p2 = head, head
60+
61+
# Advance p2 by n nodes.
62+
i = 0
63+
while p2 and i < n:
64+
p2 = p2.next
65+
i += 1
66+
67+
# Advance both pointers until p2 reaches the end, keeping track of the
68+
# node before p1.
69+
while p2:
70+
prev = p1
71+
p1 = p1.next
72+
p2 = p2.next
73+
74+
# Remove p1 by connecting prev to p1.next.
75+
prev.next = p1.next
76+
77+
return prehead.next
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
"""
2+
19. Remove Nth Node From End of List
3+
4+
https://leetcode.com/problems/remove-nth-node-from-end-of-list
5+
"""
6+
7+
from unittest import TestCase
8+
9+
from src.remove_nth_node_from_end_of_list import Solution
10+
11+
from .utils import create_linked_list_from_list, create_list_from_linked_list
12+
13+
14+
class TestSolution(TestCase):
15+
def test_1(self):
16+
exp = [1, 2, 3, 5]
17+
l1 = create_linked_list_from_list([1, 2, 3, 4, 5])
18+
ll = Solution().removeNthFromEnd(l1, 2)
19+
assert create_list_from_linked_list(ll) == exp
20+
21+
def test_2(self):
22+
exp = []
23+
l1 = create_linked_list_from_list([1])
24+
ll = Solution().removeNthFromEnd(l1, 1)
25+
assert create_list_from_linked_list(ll) == exp
26+
27+
def test_3(self):
28+
exp = [1]
29+
l1 = create_linked_list_from_list([1, 2])
30+
ll = Solution().removeNthFromEnd(l1, 1)
31+
assert create_list_from_linked_list(ll) == exp
32+
33+
def test_4(self):
34+
exp = [2]
35+
l1 = create_linked_list_from_list([1, 2])
36+
ll = Solution().removeNthFromEnd(l1, 2)
37+
assert create_list_from_linked_list(ll) == exp

0 commit comments

Comments
 (0)