#82 Remove Duplicates from Sorted List II
the problem
In plain words
Given the head of a sorted linked list, delete every node whose value appears more than once, so that only values appearing exactly once remain. Return the (still sorted) result.
in head = [1,2,3,3,4,4,5]
out [1,2,5]
in head = [1,1,1,2,3]
out [2,3]
- 0 ≤ number of nodes ≤ 300
- -100 ≤ Node.val ≤ 100
- The list is sorted in ascending order
your turn
Try it before you peek
Read the examples, say the brute force out loud, then write code: here or on LeetCode ↗. Stuck for 20 minutes? Open one hint at a time.
Solve it in the browser
LeetCode-style: complete the class. Compiled by the real javac (Java 17) and judged right here — nothing is sent anywhere.
Solutions are hidden so you can try first. Even 20 minutes of real effort makes the answer stick far better than reading it.
Marking the problem solved, or opening every hint, also shows it.
the aha
Key insight
patternIn-place linked-list rewiring
Sorted means all copies of a value sit together in one run. Keep prev on the last node you are sure to keep (a dummy at first, since the head may go). When curr starts a run, skip the whole run and link prev past it.
solutions
From brute force to optimal
Count values in a LinkedHashMap (keeps insertion order — here the input arrives sorted), then build a new list of the values counted once.
- count.merge(val, 1, Integer::sum) for every node.
- For each entry with count 1, append a new node.
One pass to count, one over the distinct values.
The map plus new nodes.
class Solution { public ListNode deleteDuplicates(ListNode head) { Map<Integer, Integer> count = new LinkedHashMap<>(); // keeps the sorted order of first sight for (ListNode p = head; p != null; p = p.next) count.merge(p.val, 1, Integer::sum); ListNode dummy = new ListNode(); ListNode tail = dummy; for (Map.Entry<Integer, Integer> e : count.entrySet()) { if (e.getValue() == 1) { // keep values seen exactly once tail.next = new ListNode(e.getKey()); tail = tail.next; } } return dummy.next; }}If curr and curr.next share a value, move curr past every node with that value and set prev.next = curr. Otherwise keep curr: prev = curr.
- dummy → head; prev = dummy; curr = head.
- If curr.next has the same value: remember it, skip the run, prev.next = curr.
- Else prev = curr; curr = curr.next.
- Return dummy.next.
curr moves forward over every node exactly once.
Two references and a dummy.
class Solution { public ListNode deleteDuplicates(ListNode head) { ListNode dummy = new ListNode(0, head); // the head itself may be a duplicate ListNode prev = dummy; // last node we are sure to keep ListNode curr = head; while (curr != null) { if (curr.next != null && curr.val == curr.next.val) { int dup = curr.val; while (curr != null && curr.val == dup) curr = curr.next; // skip the whole run prev.next = curr; // unlink every copy at once } else { prev = curr; // a unique value: keep it curr = curr.next; } } return dummy.next; }}in the room
How to say it in the interview
talk track
- Contrast with LC 83 (keep one copy): here every copy goes, so you need the node before the run —
prev. - Dummy, because the head itself may be deleted (example 2).
- Only advance
prevwhen the current value is unique.
traps
- Advancing
prevright after removing a run — the next node might start another run ([1,1,2,2]). - Returning
headinstead ofdummy.nextwhen the first values are duplicates.
what they ask next
Follow-ups
Keep one copy of each value instead (LC 83)?
Simpler: if curr.val == curr.next.val, curr.next = curr.next.next; else curr = curr.next. No dummy needed — the head always stays.
What if the list were unsorted?
Count values in a HashMap in a first pass, then remove every node whose count is above 1 in a second pass (with a dummy).
before you submit
Edge cases to test
- Empty list → null.
- Everything repeats ([1,1,2,2]) → an empty list.
- The head repeats → the head changes.
- The tail repeats → the list ends at prev.
practise next
Similar problems
- #26Remove Duplicates from Sorted ArrayEasyin Two Pointers
- #19Remove Nth Node From End of ListMediumin Linked Lists
- #217Contains DuplicateEasyin Hashing