Skip to main content

66. Remove Duplicates from Sorted List II

mediumAsked at Snowflake

Remove all nodes from a sorted linked list that have duplicates, leaving only distinct values. Snowflake asks this to test the dummy-head + look-ahead pattern — same shape as stream-side DISTINCT processing.

By Alex Chen, Founder, InterviewChamp.AI · Last verified

Source citations

Public interview reports confirming this problem appears in Snowflake loops.

  • Glassdoor (2025-Q4)Snowflake execution-engine team uses this in onsites.
  • LeetCode Discuss (2025-09)Reported at Snowflake SDE-I screens.

Problem

Given the head of a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. Return the linked list sorted as well.

Constraints

  • 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.

Examples

Example 1

Input
head = [1,2,3,3,4,4,5]
Output
[1,2,5]

Example 2

Input
head = [1,1,1,2,3]
Output
[2,3]

Approaches

1. Two-pass (count + filter)

First pass: count occurrences. Second pass: emit only count == 1 values.

Time
O(n)
Space
O(n)
// outline only — works but two passes and a map.

Tradeoff: Two passes, O(n) extra. Works.

2. Dummy head + look-ahead (optimal)

Use dummy node before head. Maintain prev. When curr.val == curr.next.val, advance curr past all duplicates; link prev.next = curr.next. Otherwise advance prev.

Time
O(n)
Space
O(1)
function deleteDuplicates(head) {
  const dummy = { val: 0, next: head };
  let prev = dummy;
  while (head) {
    if (head.next && head.val === head.next.val) {
      while (head.next && head.val === head.next.val) head = head.next;
      prev.next = head.next;
    } else {
      prev = prev.next;
    }
    head = head.next;
  }
  return dummy.next;
}

Tradeoff: Single pass, O(1) state. The look-ahead pattern handles 'skip all duplicates' cleanly.

Snowflake-specific tips

Snowflake interviewers want the dummy-head pattern explicitly stated. Bonus signal: connect to stream-side DISTINCT — for a sorted stream, you can emit a value only if it's unique in its run, exactly this pattern.

Common mistakes

  • Not using a dummy head — special-case logic for removing the head node gets tangled.
  • Advancing prev when you shouldn't (when you've skipped duplicates).
  • Skipping past one duplicate but not all — must inner-loop until next differs.

Follow-up questions

An interviewer at Snowflake may pivot to one of these next:

  • Remove Duplicates from Sorted List (LC 83) — keep one copy.
  • How does Snowflake implement stream DISTINCT?
  • Generalize to 'keep at most k'.

Solve it now

Free. No sign-up. Python and JavaScript run instantly in your browser.

Output

Press Run or Cmd+Enter to execute

FAQ

Why advance prev only in the else branch?

When we've removed duplicates, prev should still point at the same node — but its .next has changed. Advancing prev in this case would skip the new connection.

How does stream DISTINCT work?

On a sorted stream, you emit a value only when its run length is 1. The look-ahead pattern naturally handles this. For unsorted streams, you'd need a hash set.

Practice these live with InterviewChamp.AI

Drill Remove Duplicates from Sorted List II and other Snowflake interview questions under real-loop conditions with instant feedback on your reasoning, complexity claims, and code.

Practice these live with InterviewChamp.AI →