Remove Duplicates from Sorted List
Given the head of a sorted (ascending) linked list, delete nodes so that each distinct value appears exactly once, keeping one copy of each. The result stays sorted. Modify the list in place and return its head — the head value is the smallest, so it is never the copy that gets removed, and the head pointer is unchanged. An empty list returns an empty list.
- The number of nodes in the list is in the range [0, 300]
- -100 <= Node.val <= 100
- The list is guaranteed to be sorted in ascending order.
head = [1,1,2][1,2]head = [1,1,2,3,3][1,2,3]head = [1,1,1][1]If you have a list like [1, 1, 2], you want it to become [1, 2]. Since the list is already sorted, we know that any identical numbers must be sitting right next to each other.
If the list weren't sorted, we'd have to keep a separate "Seen" set in our pocket. Every time we saw a number, we'd check if it was in our set. If it was, we'd delete it. This would take O(N) extra space.
seen = set()
while curr:
if curr.val in seen: delete(curr)
else: seen.add(curr.val)Because our list is sorted, we don't need a "Seen" set. We just look at our immediate neighbor.
- If my neighbor has the same value as me, I "skip" them by pointing my next to my neighbor's next.
- Important: After skipping, I don't move forward yet! I stay on the same node and check my new neighbor, just in case there's another duplicate (like [1, 1, 1]).
We use a single pointer to walk through the list. We only move it forward when we are absolutely sure our neighbor is different.
curr = head
while curr and curr.next:
if curr.val == curr.next.val:
# Neighbor is a duplicate! Point past it.
curr.next = curr.next.next
else:
# Neighbor is different! Safe to move.
curr = curr.next
return headPointer Reassignment
next.val == curr.val