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.
[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>usingnamespacestd;classNode{public:intdata;Node*next;Node(intx){data=x;next=nullptr;}};Node*removeDuplicates(Node*head){unordered_map<int,int>freq;Node*curr=head;// Store frequency of each node valuewhile(curr){freq[curr->data]++;curr=curr->next;}Node*dummy=newNode(-1);dummy->next=head;Node*prev=dummy;curr=head;// Remove nodes having frequency > 1while(curr){if(freq[curr->data]>1){prev->next=curr->next;}else{prev=curr;}curr=curr->next;}Node*newHead=dummy->next;deletedummy;returnnewHead;}// Function to print linked listvoidprintList(Node*head){if(!head){cout<<"Empty list";return;}while(head){cout<<head->data<<" ";head=head->next;}}// Driver Codeintmain(){Node*head=newNode(23);head->next=newNode(28);head->next->next=newNode(28);head->next->next->next=newNode(35);head->next->next->next->next=newNode(49);head->next->next->next->next->next=newNode(49);head=removeDuplicates(head);printList(head);return0;}
Java
importjava.util.HashMap;classNode{publicintdata;publicNodenext;publicNode(intx){data=x;next=null;}}publicclassGFG{publicstaticNoderemoveDuplicates(Nodehead){HashMap<Integer,Integer>freq=newHashMap<>();Nodecurr=head;// Store frequency of each node valuewhile(curr!=null){freq.put(curr.data,freq.getOrDefault(curr.data,0)+1);curr=curr.next;}Nodedummy=newNode(-1);dummy.next=head;Nodeprev=dummy;curr=head;// Remove nodes having frequency > 1while(curr!=null){if(freq.get(curr.data)>1){prev.next=curr.next;}else{prev=curr;}curr=curr.next;}NodenewHead=dummy.next;// No need to delete dummy as Java has garbage// collectionreturnnewHead;}// Function to print linked listpublicstaticvoidprintList(Nodehead){if(head==null){System.out.println("Empty list");return;}while(head!=null){System.out.print(head.data+" ");head=head.next;}}// Driver Codepublicstaticvoidmain(String[]args){Nodehead=newNode(23);head.next=newNode(28);head.next.next=newNode(28);head.next.next.next=newNode(35);head.next.next.next.next=newNode(49);head.next.next.next.next.next=newNode(49);head=removeDuplicates(head);printList(head);}}
Python
classNode:def__init__(self,x):self.data=xself.next=NonedefremoveDuplicates(head):freq={}curr=head# Store frequency of each node valuewhilecurr:freq[curr.data]=freq.get(curr.data,0)+1curr=curr.nextdummy=Node(-1)dummy.next=headprev=dummycurr=head# Remove nodes having frequency > 1whilecurr:iffreq[curr.data]>1:prev.next=curr.nextelse:prev=currcurr=curr.nextnewHead=dummy.next# No need to delete dummy as Python has garbage collectionreturnnewHead# Function to print linked listdefprintList(head):ifnothead:print('Empty list')returnwhilehead:print(head.data,end=' ')head=head.next# Driver Codeif__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#
usingSystem;usingSystem.Collections.Generic;publicclassNode{publicintdata;publicNodenext;publicNode(intx){data=x;next=null;}}publicclassGFG{publicstaticNoderemoveDuplicates(Nodehead){Dictionary<int,int>freq=newDictionary<int,int>();Nodecurr=head;// Store frequency of each node valuewhile(curr!=null){if(freq.ContainsKey(curr.data))freq[curr.data]++;elsefreq[curr.data]=1;curr=curr.next;}Nodedummy=newNode(-1);dummy.next=head;Nodeprev=dummy;curr=head;// Remove nodes having frequency > 1while(curr!=null){if(freq[curr.data]>1){prev.next=curr.next;}else{prev=curr;}curr=curr.next;}NodenewHead=dummy.next;// No need to delete dummy as C# has garbage// collectionreturnnewHead;}// Function to print linked listpublicstaticvoidprintList(Nodehead){if(head==null){Console.WriteLine("Empty list");return;}while(head!=null){Console.Write(head.data+" ");head=head.next;}}// Driver CodepublicstaticvoidMain(){Nodehead=newNode(23);head.next=newNode(28);head.next.next=newNode(28);head.next.next.next=newNode(35);head.next.next.next.next=newNode(49);head.next.next.next.next.next=newNode(49);head=removeDuplicates(head);printList(head);}}
JavaScript
classNode{constructor(x){this.data=x;this.next=null;}}functionremoveDuplicates(head){letfreq=newMap();letcurr=head;// Store frequency of each node valuewhile(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;}letdummy=newNode(-1);dummy.next=head;letprev=dummy;curr=head;// Remove nodes having frequency > 1while(curr!=null){if(freq.get(curr.data)>1){prev.next=curr.next;}else{prev=curr;}curr=curr.next;}letnewHead=dummy.next;// No need to delete dummy as JavaScript has garbage collectionreturnnewHead;}// Function to print linked listfunctionprintList(head){if(!head){console.log('Empty list');return;}letcurrent=head;while(current!=null){console.log(current.data+'');current=current.next;}}// Driver Codelethead=newNode(23);head.next=newNode(28);head.next.next=newNode(28);head.next.next.next=newNode(35);head.next.next.next.next=newNode(49);head.next.next.next.next.next=newNode(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>usingnamespacestd;classNode{public:intdata;Node*next;Node(intx){data=x;next=nullptr;}};Node*removeDuplicates(Node*head){// create a dummy node that acts like a fake// head of list pointing to the original headNode*dummy=newNode(-1);// dummy node points to the original headdummy->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 currentwhile(curr->next!=nullptr&&prev->next->data==curr->next->data){curr=curr->next;}// If current has not moved, then the node is uniqueif(prev->next==curr){prev=prev->next;}else{// Otherwise, move prev's next pointer to skip duplicatesprev->next=curr->next;}curr=curr->next;}Node*newHead=dummy->next;deletedummy;returnnewHead;}// Function to print linked listvoidprintList(Node*head){if(!head){cout<<"Empty list";return;}while(head){cout<<head->data<<" ";head=head->next;}}// Driver Codeintmain(){Node*head=newNode(23);head->next=newNode(28);head->next->next=newNode(28);head->next->next->next=newNode(35);head->next->next->next->next=newNode(49);head->next->next->next->next->next=newNode(49);head=removeDuplicates(head);printList(head);return0;}
Java
classNode{intdata;Nodenext;Node(intx){data=x;next=null;}}publicclassGFG{publicstaticNoderemoveDuplicates(Nodehead){// create a dummy node that acts like a fake// head of list pointing to the original headNodedummy=newNode(-1);// dummy node points to the original headdummy.next=head;// Node pointing to last node which has no// duplicate.Nodeprev=dummy;// Node used to traverse the linked list.Nodecurr=head;while(curr!=null){// Until the current and next values are// same, keep updating currentwhile(curr.next!=null&&prev.next.data==curr.next.data){curr=curr.next;}// If current has not moved, then the node is// uniqueif(prev.next==curr){prev=prev.next;}else{// Otherwise, move prev's next pointer to// skip duplicatesprev.next=curr.next;}curr=curr.next;}NodenewHead=dummy.next;returnnewHead;}// Function to print linked listpublicstaticvoidprintList(Nodehead){if(head==null){System.out.println("Empty list");return;}while(head!=null){System.out.print(head.data+" ");head=head.next;}}// Driver Codepublicstaticvoidmain(String[]args){Nodehead=newNode(23);head.next=newNode(28);head.next.next=newNode(28);head.next.next.next=newNode(35);head.next.next.next.next=newNode(49);head.next.next.next.next.next=newNode(49);head=removeDuplicates(head);printList(head);}}
Python
classNode:def__init__(self,x):self.data=xself.next=NonedefremoveDuplicates(head):# create a dummy node that acts like a fake# head of list pointing to the original headdummy=Node(-1)# dummy node points to the original headdummy.next=head# Node pointing to last node which has no duplicate.prev=dummy# Node used to traverse the linked list.curr=headwhilecurrisnotNone:# Until the current and next values are# same, keep updating currentwhilecurr.nextisnotNoneandprev.next.data==curr.next.data:curr=curr.next# If current has not moved, then the node is uniqueifprev.next==curr:prev=prev.nextelse:# Otherwise, move prev's next pointer to skip duplicatesprev.next=curr.nextcurr=curr.nextnewHead=dummy.nextreturnnewHead# Function to print linked listdefprintList(head):ifheadisNone:print('Empty list')returnwhileheadisnotNone:print(head.data,end=' ')head=head.next# Driver Codeif__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#
usingSystem;publicclassNode{publicintdata;publicNodenext;publicNode(intx){data=x;next=null;}}publicclassGFG{publicstaticNoderemoveDuplicates(Nodehead){// create a dummy node that acts like a fake// head of list pointing to the original headNodedummy=newNode(-1);// dummy node points to the original headdummy.next=head;// Node pointing to last node which has no// duplicate.Nodeprev=dummy;// Node used to traverse the linked list.Nodecurr=head;while(curr!=null){// Until the current and next values are// same, keep updating currentwhile(curr.next!=null&&prev.next.data==curr.next.data){curr=curr.next;}// If current has not moved, then the node is// uniqueif(prev.next==curr){prev=prev.next;}else{// Otherwise, move prev's next pointer to// skip duplicatesprev.next=curr.next;}curr=curr.next;}NodenewHead=dummy.next;returnnewHead;}// Function to print linked listpublicstaticvoidprintList(Nodehead){if(head==null){Console.WriteLine("Empty list");return;}while(head!=null){Console.Write(head.data+" ");head=head.next;}}// Driver CodepublicstaticvoidMain(){Nodehead=newNode(23);head.next=newNode(28);head.next.next=newNode(28);head.next.next.next=newNode(35);head.next.next.next.next=newNode(49);head.next.next.next.next.next=newNode(49);head=removeDuplicates(head);printList(head);}}
JavaScript
classNode{constructor(x){this.data=x;this.next=null;}}functionremoveDuplicates(head){// create a dummy node that acts like a fake// head of list pointing to the original headletdummy=newNode(-1);// dummy node points to the original headdummy.next=head;// Node pointing to last node which has no duplicate.letprev=dummy;// Node used to traverse the linked list.letcurr=head;while(curr!==null){// Until the current and next values are// same, keep updating currentwhile(curr.next!==null&&prev.next.data===curr.next.data){curr=curr.next;}// If current has not moved, then the node is uniqueif(prev.next===curr){prev=prev.next;}else{// Otherwise, move prev's next pointer to skip duplicatesprev.next=curr.next;}curr=curr.next;}letnewHead=dummy.next;returnnewHead;}// Function to print linked listfunctionprintList(head){if(!head){console.log('Empty list');return;}while(head!==null){process.stdout.write(head.data+'');head=head.next;}}// Driver Codelethead=newNode(23);head.next=newNode(28);head.next.next=newNode(28);head.next.next.next=newNode(35);head.next.next.next.next=newNode(49);head.next.next.next.next.next=newNode(49);head=removeDuplicates(head);printList(head);