Remove duplicates from a sorted DLL

easy

You are given the head of a doubly linked list whose nodes are already sorted in non-decreasing order of their val. Remove every duplicate node so that each value appears exactly once, keeping the first occurrence of each value, and return the head of the updated list.

Each node stores an integer in val and holds two pointers: next (to the node after it) and prev (to the node before it). When you drop a duplicate, the surviving neighbours on both sides must be stitched back together in both directions — the node before the deleted run must point forward past it, and the node after it must point its prev back.

Because the list is sorted, all copies of a value sit next to each other, so you never have to search — the only place a duplicate can hide is immediately after the node you are standing on.

The list is serialized as space-separated values from head to tail, and the answer is printed the same way.

Hints

The list is sorted — so where can two nodes with the same value possibly be relative to each other?
You never need to search for a duplicate; if one exists, it is sitting directly after the node you are on.
Anchor on the node you keep and repeatedly splice out its next node while the values match — only step forward on a mismatch.

Common doubts

No. Because the list is sorted, equal values are adjacent, so comparing each node with its immediate next is enough. The set works but costs O(n) extra space.
The first occurrence. You stand on it and delete the copies that follow, so the earliest node of each value is the one kept.
Two: set curr.next to skip the deleted node, and set the new curr.next.prev back to curr (guarding against null when the deleted node was the tail).

Interview follow-ups

Fall back to the hash-set approach — record each seen value and unlink any node whose value repeats — which is O(n) time and O(n) space and order-independent.
Detect a run whose length exceeds one and splice out the entire run, connecting the node before the run to the node after it — a small extension of the same neighbour-comparison walk.

Fun facts

  • The same 'sorted ⇒ duplicates are adjacent' trick powers dedup on sorted arrays and the classic merge step of merge sort.
  • This in-place splice is the doubly-linked-list cousin of the two-pointer 'remove duplicates from sorted array' pattern — same idea, different container.

Asked at

AmazonMicrosoftAdobeGoogle
Frequently Sometimes Occasionally
Example 1
Input: head = 1 <-> 1 <-> 1 <-> 2 <-> 3 <-> 4
Output: 1 <-> 2 <-> 3 <-> 4
Only the first occurrence of value 1 is kept; the two extra 1s are removed.
Example 2
Input: head = 1 <-> 2 <-> 2 <-> 3 <-> 3 <-> 4 <-> 4
Output: 1 <-> 2 <-> 3 <-> 4
The repeated 2, 3, and 4 nodes are deleted, leaving one of each.
Constraints

- 1 <= n <= 10^5 - The list is sorted in non-decreasing order of val. - Node values fit in a 32-bit signed integer.

Solve this problem →