Remove all occurrences of duplicates from a sorted Linked List

Last Updated : 19 Jun, 2026

Given the head of a sorted linked list, remove all nodes that have duplicate values, retaining only nodes whose values appear exactly once. Return the head of the updated linked list.

Examples:

Input: head = 23 -> 28 -> 28 -> 35 -> 49 -> 49
Output: 23 35
Explanation:

blobid0_1781074564

The duplicate numbers are 28 and 49 which are removed from the list.

Input: head = 11 -> 11 -> 75 -> 75
Output: Empty list
Explanation:

blobid0_1781084367

All the nodes in the linked list have duplicates. Hence the resultant list would be empty.

Try It Yourself
redirect icon

[Naive Approach] Using Frequency Map – O(n) Time and O(n) Space

The idea is to first count the frequency of each value using a hash map. Then traverse the linked list again and keep only those nodes whose frequency is exactly 1.

C++
#include <bits/stdc++.h>
using namespace std;

class Node
{
  public:
    int data;
    Node *next;

    Node(int x)
    {
        data = x;
        next = nullptr;
    }
};

Node *removeDuplicates(Node *head)
{
    unordered_map<int, int> freq;

    Node *curr = head;

    // Store frequency of each node value
    while (curr)
    {
        freq[curr->data]++;
        curr = curr->next;
    }

    Node *dummy = new Node(-1);
    dummy->next = head;

    Node *prev = dummy;
    curr = head;

    // Remove nodes having frequency > 1
    while (curr)
    {
        if (freq[curr->data] > 1)
        {
            prev->next = curr->next;
        }
        else
        {
            prev = curr;
        }

        curr = curr->next;
    }

    Node *newHead = dummy->next;
    delete dummy;

    return newHead;
}

// Function to print linked list
void printList(Node *head)
{
    if (!head)
    {
        cout << "Empty list";
        return;
    }

    while (head)
    {
        cout << head->data << " ";
        head = head->next;
    }
}

// Driver Code
int main()
{

    Node *head = new Node(23);
    head->next = new Node(28);
    head->next->next = new Node(28);
    head->next->next->next = new Node(35);
    head->next->next->next->next = new Node(49);
    head->next->next->next->next->next = new Node(49);

    head = removeDuplicates(head);

    printList(head);

    return 0;
}
Java
import java.util.HashMap;

class Node {
    public int data;
    public Node next;

    public Node(int x)
    {
        data = x;
        next = null;
    }
}

public class GFG {
    public static Node removeDuplicates(Node head)
    {
        HashMap<Integer, Integer> freq = new HashMap<>();

        Node curr = head;

        // Store frequency of each node value
        while (curr != null) {
            freq.put(curr.data,
                     freq.getOrDefault(curr.data, 0) + 1);
            curr = curr.next;
        }

        Node dummy = new Node(-1);
        dummy.next = head;

        Node prev = dummy;
        curr = head;

        // Remove nodes having frequency > 1
        while (curr != null) {
            if (freq.get(curr.data) > 1) {
                prev.next = curr.next;
            }
            else {
                prev = curr;
            }
            curr = curr.next;
        }

        Node newHead = dummy.next;
        // No need to delete dummy as Java has garbage
        // collection
        return newHead;
    }

    // Function to print linked list
    public static void printList(Node head)
    {
        if (head == null) {
            System.out.println("Empty list");
            return;
        }

        while (head != null) {
            System.out.print(head.data + " ");
            head = head.next;
        }
    }

    // Driver Code
    public static void main(String[] args)
    {
        Node head = new Node(23);
        head.next = new Node(28);
        head.next.next = new Node(28);
        head.next.next.next = new Node(35);
        head.next.next.next.next = new Node(49);
        head.next.next.next.next.next = new Node(49);

        head = removeDuplicates(head);

        printList(head);
    }
}
Python
class Node:
    def __init__(self, x):
        self.data = x
        self.next = None

def removeDuplicates(head):
    freq = {}

    curr = head

    # Store frequency of each node value
    while curr:
        freq[curr.data] = freq.get(curr.data, 0) + 1
        curr = curr.next

    dummy = Node(-1)
    dummy.next = head

    prev = dummy
    curr = head

    # Remove nodes having frequency > 1
    while curr:
        if freq[curr.data] > 1:
            prev.next = curr.next
        else:
            prev = curr
        curr = curr.next

    newHead = dummy.next
    # No need to delete dummy as Python has garbage collection
    return newHead

# Function to print linked list
def printList(head):
    if not head:
        print('Empty list')
        return

    while head:
        print(head.data, end=' ')
        head = head.next

# Driver Code
if __name__ == '__main__':
    head = Node(23)
    head.next = Node(28)
    head.next.next = Node(28)
    head.next.next.next = Node(35)
    head.next.next.next.next = Node(49)
    head.next.next.next.next.next = Node(49)

    head = removeDuplicates(head)

    printList(head)
C#
using System;
using System.Collections.Generic;

public class Node {
    public int data;
    public Node next;

    public Node(int x)
    {
        data = x;
        next = null;
    }
}

public class GFG {
    public static Node removeDuplicates(Node head)
    {
        Dictionary<int, int> freq
            = new Dictionary<int, int>();

        Node curr = head;

        // Store frequency of each node value
        while (curr != null) {
            if (freq.ContainsKey(curr.data))
                freq[curr.data]++;
            else
                freq[curr.data] = 1;
            curr = curr.next;
        }

        Node dummy = new Node(-1);
        dummy.next = head;

        Node prev = dummy;
        curr = head;

        // Remove nodes having frequency > 1
        while (curr != null) {
            if (freq[curr.data] > 1) {
                prev.next = curr.next;
            }
            else {
                prev = curr;
            }
            curr = curr.next;
        }

        Node newHead = dummy.next;
        // No need to delete dummy as C# has garbage
        // collection
        return newHead;
    }

    // Function to print linked list
    public static void printList(Node head)
    {
        if (head == null) {
            Console.WriteLine("Empty list");
            return;
        }

        while (head != null) {
            Console.Write(head.data + " ");
            head = head.next;
        }
    }

    // Driver Code
    public static void Main()
    {
        Node head = new Node(23);
        head.next = new Node(28);
        head.next.next = new Node(28);
        head.next.next.next = new Node(35);
        head.next.next.next.next = new Node(49);
        head.next.next.next.next.next = new Node(49);

        head = removeDuplicates(head);

        printList(head);
    }
}
JavaScript
class Node {
    constructor(x) {
        this.data = x;
        this.next = null;
    }
}

function removeDuplicates(head) {
    let freq = new Map();

    let curr = head;

    // Store frequency of each node value
    while (curr!= null) {
        if (freq.has(curr.data)) {
            freq.set(curr.data, freq.get(curr.data) + 1);
        } else {
            freq.set(curr.data, 1);
        }
        curr = curr.next;
    }

    let dummy = new Node(-1);
    dummy.next = head;

    let prev = dummy;
    curr = head;

    // Remove nodes having frequency > 1
    while (curr!= null) {
        if (freq.get(curr.data) > 1) {
            prev.next = curr.next;
        } else {
            prev = curr;
        }
        curr = curr.next;
    }

    let newHead = dummy.next;
    // No need to delete dummy as JavaScript has garbage collection
    return newHead;
}

// Function to print linked list
function printList(head) {
    if (!head) {
        console.log('Empty list');
        return;
    }

    let current = head;
    while (current!= null) {
        console.log(current.data +'');
        current = current.next;
    }
}

// Driver Code
let head = new Node(23);
head.next = new Node(28);
head.next.next = new Node(28);
head.next.next.next = new Node(35);
head.next.next.next.next = new Node(49);
head.next.next.next.next.next = new Node(49);

head = removeDuplicates(head);

printList(head);

Output
23 35 

Time Complexity: O(n)
Auxiliary Space: O(n)

[Expected Approach] Using Single Traversal of Sorted List – O(n) Time and O(1) Space

The idea is to use the sorted nature of the linked list. Since duplicate values appear consecutively, traverse each duplicate group and remove the entire group if its size is greater than one. A dummy node helps handle duplicate nodes occurring at the beginning of the list.

Let us understand with example:
Input: head = 23 -> 28 -> 28 -> 35 -> 49 -> 49

  • Create a dummy node before the head and initialize prev = dummy, curr = head.
  • Node 23 is unique, so move both pointers forward (prev = 23, curr = 28).
  • Nodes 28, 28 form a duplicate group, so link 23 directly to 35, removing all 28s.
  • Node 35 is unique, so move prev to 35 and curr to 49.
  • Nodes 49, 49 form a duplicate group, so remove them by setting 35->next = nullptr.

Final Linked List: 23 -> 35

C++
#include <bits/stdc++.h>
using namespace std;

class Node
{
  public:
    int data;
    Node *next;

    Node(int x)
    {
        data = x;
        next = nullptr;
    }
};

Node *removeDuplicates(Node *head)
{

    // create a dummy node that acts like a fake
    // head of list pointing to the original head
    Node *dummy = new Node(-1);

    // dummy node points to the original head
    dummy->next = head;

    // Node pointing to last node which has no duplicate.
    Node *prev = dummy;

    // Node used to traverse the linked list.
    Node *curr = head;

    while (curr != nullptr)
    {
        // Until the current and next values are
        // same, keep updating current
        while (curr->next != nullptr && prev->next->data == curr->next->data)
        {
            curr = curr->next;
        }

        // If current has not moved, then the node is unique
        if (prev->next == curr)
        {
            prev = prev->next;
        }
        else
        {
            // Otherwise, move prev's next pointer to skip duplicates
            prev->next = curr->next;
        }

        curr = curr->next;
    }

    Node *newHead = dummy->next;
    delete dummy;
    return newHead;
}

// Function to print linked list
void printList(Node *head)
{
    if (!head)
    {
        cout << "Empty list";
        return;
    }

    while (head)
    {
        cout << head->data << " ";
        head = head->next;
    }
}

// Driver Code
int main()
{

    Node *head = new Node(23);
    head->next = new Node(28);
    head->next->next = new Node(28);
    head->next->next->next = new Node(35);
    head->next->next->next->next = new Node(49);
    head->next->next->next->next->next = new Node(49);

    head = removeDuplicates(head);

    printList(head);

    return 0;
}
Java
class Node {
    int data;
    Node next;

    Node(int x)
    {
        data = x;
        next = null;
    }
}

public class GFG {
    public static Node removeDuplicates(Node head)
    {
        // create a dummy node that acts like a fake
        // head of list pointing to the original head
        Node dummy = new Node(-1);

        // dummy node points to the original head
        dummy.next = head;

        // Node pointing to last node which has no
        // duplicate.
        Node prev = dummy;

        // Node used to traverse the linked list.
        Node curr = head;

        while (curr != null) {
            // Until the current and next values are
            // same, keep updating current
            while (curr.next != null
                   && prev.next.data == curr.next.data) {
                curr = curr.next;
            }

            // If current has not moved, then the node is
            // unique
            if (prev.next == curr) {
                prev = prev.next;
            }
            else {
                // Otherwise, move prev's next pointer to
                // skip duplicates
                prev.next = curr.next;
            }

            curr = curr.next;
        }

        Node newHead = dummy.next;
        return newHead;
    }

    // Function to print linked list
    public static void printList(Node head)
    {
        if (head == null) {
            System.out.println("Empty list");
            return;
        }

        while (head != null) {
            System.out.print(head.data + " ");
            head = head.next;
        }
    }

    // Driver Code
    public static void main(String[] args)
    {
        Node head = new Node(23);
        head.next = new Node(28);
        head.next.next = new Node(28);
        head.next.next.next = new Node(35);
        head.next.next.next.next = new Node(49);
        head.next.next.next.next.next = new Node(49);

        head = removeDuplicates(head);

        printList(head);
    }
}
Python
class Node:
    def __init__(self, x):
        self.data = x
        self.next = None

def removeDuplicates(head):
    # create a dummy node that acts like a fake
    # head of list pointing to the original head
    dummy = Node(-1)

    # dummy node points to the original head
    dummy.next = head

    # Node pointing to last node which has no duplicate.
    prev = dummy

    # Node used to traverse the linked list.
    curr = head

    while curr is not None:
        # Until the current and next values are
        # same, keep updating current
        while curr.next is not None and prev.next.data == curr.next.data:
            curr = curr.next

        # If current has not moved, then the node is unique
        if prev.next == curr:
            prev = prev.next
        else:
            # Otherwise, move prev's next pointer to skip duplicates
            prev.next = curr.next

        curr = curr.next

    newHead = dummy.next
    return newHead

# Function to print linked list
def printList(head):
    if head is None:
        print('Empty list')
        return

    while head is not None:
        print(head.data, end=' ')
        head = head.next

# Driver Code
if __name__ == '__main__':
    head = Node(23)
    head.next = Node(28)
    head.next.next = Node(28)
    head.next.next.next = Node(35)
    head.next.next.next.next = Node(49)
    head.next.next.next.next.next = Node(49)

    head = removeDuplicates(head)

    printList(head)
C#
using System;

public class Node {
    public int data;
    public Node next;

    public Node(int x)
    {
        data = x;
        next = null;
    }
}

public class GFG {
    public static Node removeDuplicates(Node head)
    {
        // create a dummy node that acts like a fake
        // head of list pointing to the original head
        Node dummy = new Node(-1);

        // dummy node points to the original head
        dummy.next = head;

        // Node pointing to last node which has no
        // duplicate.
        Node prev = dummy;

        // Node used to traverse the linked list.
        Node curr = head;

        while (curr != null) {
            // Until the current and next values are
            // same, keep updating current
            while (curr.next != null
                   && prev.next.data == curr.next.data) {
                curr = curr.next;
            }

            // If current has not moved, then the node is
            // unique
            if (prev.next == curr) {
                prev = prev.next;
            }
            else {
                // Otherwise, move prev's next pointer to
                // skip duplicates
                prev.next = curr.next;
            }

            curr = curr.next;
        }

        Node newHead = dummy.next;
        return newHead;
    }

    // Function to print linked list
    public static void printList(Node head)
    {
        if (head == null) {
            Console.WriteLine("Empty list");
            return;
        }

        while (head != null) {
            Console.Write(head.data + " ");
            head = head.next;
        }
    }

    // Driver Code
    public static void Main()
    {
        Node head = new Node(23);
        head.next = new Node(28);
        head.next.next = new Node(28);
        head.next.next.next = new Node(35);
        head.next.next.next.next = new Node(49);
        head.next.next.next.next.next = new Node(49);

        head = removeDuplicates(head);

        printList(head);
    }
}
JavaScript
class Node {
    constructor(x) {
        this.data = x;
        this.next = null;
    }
}

function removeDuplicates(head) {
    // create a dummy node that acts like a fake
    // head of list pointing to the original head
    let dummy = new Node(-1);

    // dummy node points to the original head
    dummy.next = head;

    // Node pointing to last node which has no duplicate.
    let prev = dummy;

    // Node used to traverse the linked list.
    let curr = head;

    while (curr!== null) {
        // Until the current and next values are
        // same, keep updating current
        while (curr.next!== null && prev.next.data === curr.next.data) {
            curr = curr.next;
        }

        // If current has not moved, then the node is unique
        if (prev.next === curr) {
            prev = prev.next;
        } else {
            // Otherwise, move prev's next pointer to skip duplicates
            prev.next = curr.next;
        }

        curr = curr.next;
    }

    let newHead = dummy.next;
    return newHead;
}

// Function to print linked list
function printList(head) {
    if (!head) {
        console.log('Empty list');
        return;
    }

    while (head!== null) {
        process.stdout.write(head.data +'');
        head = head.next;
    }
}

// Driver Code
let head = new Node(23);
head.next = new Node(28);
head.next.next = new Node(28);
head.next.next.next = new Node(35);
head.next.next.next.next = new Node(49);
head.next.next.next.next.next = new Node(49);

head = removeDuplicates(head);

printList(head);

Output
23 35 

Time Complexity: O(n)
Auxiliary Space: O(1)

Comment