Open In App

Remove Duplicates from an Unsorted Linked List

Last Updated : 03 Feb, 2025
Summarize
Comments
Improve
Suggest changes
Like Article
Like
Share
Report
News Follow

Given an unsorted linked list containing n nodes, the task is to remove duplicate nodes while preserving the original order.

Examples:

Input: 12 -> 11 -> 12 -> 21 -> 41 -> 43 -> 21 
Output: 12 -> 11 -> 21 -> 41 -> 43 
Explanation: The second occurrence of 12 (the one after 11) and the second occurrence of 21 (the one at the end) are removed, resulting in a linked list that maintains the order of their first appearances.

Input: 1 -> 2 -> 3 -> 2 -> 4
Output: 1 -> 2 -> 3 -> 4
Explanation: Similarly, the second occurrence of 2 is removed, ensuring that each number appears only once while maintaining the order of their first appearances.

[Naive Approach] Using Nested Loops – O(n^2) Time and O(1) Space

The idea is to use two loops to remove duplicates from an unsorted linked list. The first loop goes through each node one by one. For each node, the second loop checks all the nodes that come after it to see if there are any duplicates. If a duplicate is found, it removes it by changing the links. This way, we keep only the first occurrence of each number while maintaining their order.

C++
// C++ program to remove duplicates from an 
// unsorted linked list

#include <iostream>
using namespace std;

class Node {
public:
    int data;
    Node* next;
    Node(int val) {
        data = val;
        next = nullptr;
    }
};

// Function to remove duplicates using nested loops
Node* removeDuplicates(Node* head) {
    Node* curr1 = head; 

    // Traverse each node in the list
    while (curr1 != nullptr) {
        Node* curr2 = curr1; 

        // Traverse the remaining nodes to find and 
        // remove duplicates
        while (curr2->next != nullptr) {
            
            // Check if the next node has the same 
            // data as the current node
            if (curr2->next->data == curr1->data) {
                
                // Duplicate found, remove it
                Node* duplicate = curr2->next;  
                curr2->next = curr2->next->next;  

                // Free the memory of the duplicate node
                delete duplicate;
            } else {
              
                // If the next node has different data from 
                // the current node, move to the next node
                curr2 = curr2->next;
            }
        }
        
        // Move to the next node in the list
        curr1 = curr1->next;
    }
    return head;
}

void printList(Node* head) {
    Node* curr = head;
    while (curr != nullptr) {
        cout << curr->data << " ";
        curr = curr->next;
    }
    cout << endl;
}

int main() {
    
    // Create a singly linked list:
    // 12 -> 11 -> 12 -> 21 -> 41 -> 43 -> 21
    Node* head = new Node(12);
    head->next = new Node(11);
    head->next->next = new Node(12);
    head->next->next->next = new Node(21);
    head->next->next->next->next = new Node(41);
    head->next->next->next->next->next = new Node(43);
    head->next->next->next->next->next->next = new Node(21);

    head = removeDuplicates(head);
    printList(head);

    return 0;
}
C Java Python C# JavaScript

Output
12 11 21 41 43 

Time Complexity: O(n^2), Due to two nested loops
Auxiliary Space: O(1)

[Expected Approach] Using HashSet – O(n) Time and O(n) Space

In this approach, we can use a hash set to keep track of the values (nodes) that have already been seen. As we traverse the linked list, for each node, we check if its value is already in the hash set. If the value is found, it means it’s a duplicate, so we remove that node by adjusting the pointers of the previous node to skip the current one. If the value is not found, we add it to the hash set and move to the next node.

C++
// C++ implementation to remove duplicates from
// an unsorted singly linked list using hashing

#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_set<int> hashSet;
    Node *curr = head;
    Node *prev = nullptr;

    while (curr != nullptr) {

        // Check if the element is already in the hash table
        if (hashSet.find(curr->data) != hashSet.end()) {

            // Element is present, remove it
            prev->next = curr->next;

            // Delete the curr node
            Node *temp = curr;
            curr = curr->next;
            delete temp;
        }
        else {

            // Element is not present, add it to hash table
            hashSet.insert(curr->data);
            prev = curr;
            curr = curr->next;
        }
    }
    return head;
}

void printList(Node *head) {
    Node *curr = head;
    while (curr != nullptr) {
        cout << curr->data << " ";
        curr = curr->next;
    }
    cout << endl;
}

int main() {

    // Create a singly linked list:
    // 12 -> 11 -> 12 -> 21 -> 41 -> 43 -> 21
    Node* head = new Node(12);
    head->next = new Node(11);
    head->next->next = new Node(12);
    head->next->next->next = new Node(21);
    head->next->next->next->next = new Node(41);
    head->next->next->next->next->next = new Node(43);
    head->next->next->next->next->next->next = new Node(21);

    head = removeDuplicates(head);
    printList(head);

    return 0;
}
Java Python C# JavaScript

Output
12 11 21 41 43 

Time Complexity: O(n), where n are the number of nodes in the linked list.
Auxiliary Space: O(n)



Next Article

Similar Reads

three90RightbarBannerImg