Day 60: Python Remove Nth Node From End of Linked List, Two-Pointer Magic to Delete in One Pass (LeetCode #19 Style)
Source: Dev.to
Day 60 – Remove Nth Node From End of Linked List
Welcome to Day 60 of the #80DaysOfChallenges journey! This intermediate challenge solves the iconic Remove Nth Node From End of Linked List problem (LeetCode #19) using a two‑pointer technique that finds and deletes the target node in a single pass with O(1) extra space. The solution includes a Node class, helper functions for building and printing a linked list, and a main routine for interactive testing.
Example
List 1 → 2 → 3 → 4 → 5, n = 2 → 1 → 2 → 3 → 5 (remove 4, the second node from the end)
Key Takeaways
Node Class and Builder: Easy List Construction
class Node:
"""Simple singly linked list node."""
def __init__(self, value: int):
self.value = value
self.next = None
def build_linked_list(values: list[int]) -> Node:
"""Build a linked list from a list of integers."""
if not values:
return None
head = Node(values[0])
curr = head
for v in values[1:]:
curr.next = Node(v)
curr = curr.next
return head
O(n) build time; gracefully handles an empty input list.
Removal Function: Dummy Head and Two‑Pointer Dance
def remove_nth_from_end(head: Node, n: int) -> Node:
"""
Remove the Nth node from the end using fast/slow pointers.
Returns the new head after deletion.
"""
dummy = Node(0) # Simplifies edge cases (e.g., deleting the head)
dummy.next = head
fast = dummy
slow = dummy
# Move fast pointer n+1 steps ahead
for _ in range(n + 1):
if fast is None:
return head # n is larger than the list length
fast = fast.next
# Advance both pointers until fast reaches the end
while fast is not None:
fast = fast.next
slow = slow.next
# Delete the target node
slow.next = slow.next.next
return dummy.next
The dummy node removes the need for special‑case handling of head deletion. By advancing fast n+1 steps, slow ends up just before the node to delete, enabling a single‑pass O(n) solution.
Printer and Main: Visualization and Input
def print_linked_list(head: Node) -> None:
"""Print linked list values cleanly."""
curr = head
nodes = []
while curr is not None:
nodes.append(str(curr.value))
curr = curr.next
print(f"Linked List: {' -> '.join(nodes)}")
# Interactive demo
raw_nums = input("Enter list values (space-separated): ").strip()
raw_n = input("Enter n (which node from the end to remove): ").strip()
if not raw_nums or not raw_n:
print("Invalid input. Exiting.")
exit()
nums = list(map(int, raw_nums.split()))
n = int(raw_n)
head = build_linked_list(nums)
print("Original list:")
print_linked_list(head)
new_head = remove_nth_from_end(head, n)
print(f"List after removing {n}th node from the end:")
print_linked_list(new_head)
The script parses space‑separated integers, builds the list, displays the original structure, performs the removal, and prints the resulting list.
Summary and Reflections
This problem showcases the elegance of the two‑pointer technique for accessing elements from the end of a singly linked list without first computing its length.
- Dummy head utility – eliminates edge‑case checks for head deletion.
- Pointer spacing – keeping
fastn+1nodes ahead alignsslowperfectly before the target. - One‑pass efficiency – O(n) time, O(1) extra space.
Recursive approaches are possible but iterative solutions are safer for deep lists.
Next Steps and Resources
- Source code for Challenge #60 – scripts/remove_nth_from_end.py
- Main repository – 80-days-of-challenges
- Daily updates – Twitter/X (@Shahrouzlogs)