Remove Duplicates from a Sorted Doubly Linked List

Solve this Problem
Easy10–15 min
Topics
Companies
Practice:GFG ↗
Given the head of a doubly linked list already sorted in non-decreasing order, remove all duplicate values so each distinct value appears exactly once — keeping the list's relative order — and return the head. Since the list is sorted, duplicates are never scattered — they're always neighbors. That means each node only ever needs to check the one node right after it: no hash set or extra pass is needed to know whether a value has been seen before, unlike the unsorted "delete all occurrences of a key" problem.

Test Case 1:

Input:head = [1, 1, 2, 3, 3, 3, 7, 9, 9]
Output:[1, 2, 3, 7, 9]
Explanation:Consecutive runs of equal values collapse to one node each.

Test Case 2:

Input:head = [2, 2, 2]
Output:[2]
Explanation:The whole list is one run — it collapses to a single node.

Test Case 3:

Input:head = [1, 2, 3]
Output:[1, 2, 3]
Explanation:No value repeats, so nothing changes.

Constraints

  • 0 ≤ number of nodes in head ≤ 200
  • -1000 ≤ node value ≤ 1000
  • head is already sorted in non-decreasing order, so every duplicate of a value sits consecutively
🚀

Try the Dry Run

Don't just read the solution — watch it execute, one step at a time.

Approach & Solutions

Brute Force — Filter Consecutive Duplicates into a New Array

Good

Walk the list once, copying a value into an output array only when it differs from the array's last entry so far (skipping it whenever it repeats the previous value), then build a brand-new list from that array. Straightforward, but it allocates an array (and a whole new chain of nodes) the size of the deduplicated list.

TimeO(n)
SpaceO(n)
1// Node definition used in this problem: 2// class Node { 3// int val; 4// Node next; 5// } 6 7class Solution { 8 public Node removeDupSortedDLL(Node head) { 9 List<Integer> kept = new ArrayList<>(); 10 Node curr = head; 11 while (curr != null) { 12 if (kept.isEmpty() || kept.get(kept.size() - 1) != curr.val) { 13 kept.add(curr.val); 14 } 15 curr = curr.next; 16 } 17 Node dummy = new Node(0); 18 Node tail = dummy; 19 for (int v : kept) { 20 tail.next = new Node(v); 21 tail = tail.next; 22 } 23 return dummy.next; 24 } 25}

Optimal — Bypass a Repeat as Soon as It's Seen

Optimal

Because the list is already sorted, every duplicate of a value is right next to it — there's no need to remember anything beyond the current node. Compare each node to the one after it: while the next node holds the same value, skip straight past it by redirecting curr.next; only advance curr once the next node's value actually differs. In a true doubly linked list, the node that survives would also get its .prev kept pointed correctly.

TimeO(n)
SpaceO(1) extra
1// Node definition used in this problem: 2// class Node { 3// int val; 4// Node next; 5// } 6 7class Solution { 8 public Node removeDupSortedDLL(Node head) { 9 Node curr = head; 10 while (curr != null && curr.next != null) { 11 if (curr.val == curr.next.val) { 12 curr.next = curr.next.next; 13 } else { 14 curr = curr.next; 15 } 16 } 17 return head; 18 } 19}

Related Problems