Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Modify a Linked List to contain last occurrences of every duplicate element

  • Last Updated : 29 Nov, 2021

Given an unsorted Singly Linked List consisting of N nodes that may contain duplicate elements, the task is to remove all but the last occurrence of duplicate elements from the Linked List.

Examples:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Input: 1 -> 2 -> 7 -> 3 -> 2 -> 5 -> 1
Output: 7 -> 3 -> 2 -> 5 -> 1
Explanation: 
Given Linked List: 1 -> 2 -> 7 -> 3 -> 2 -> 5 -> 1
Duplicate elements: 1, 2
Modified Linked List: 7 -> 3 -> 2 -> 5 -> 1



Input: 1 -> 2 -> 3 -> 4 -> 5
Output: 1 -> 2 -> 3 -> 4 -> 5

Approach: Follow the steps below to solve the problem:

  • Initialize a dummy node and make it’s next point to head.
  • Reverse the given Linked List.
  • Initialize an unordered set, say visited, to store the already visited nodes.
  • Initialize two nodes, say currnode, pointing to the dummy node, and nextnode, to store the next node of the current node.
  • Iterate over the linked list and check if data of the next node of the current node is already visited or not.
  • If it is already visited, then perform the following steps:
    • Initialize a new node, say duplicate, to store the nextnode which is a duplicate node in this case.
    • Make current’s next point to next of the nextnode.
  • Otherwise:
    • Insert the data of nextnode into the visited set.
    • Make nextnode as currentnode.
  • Finally, reverse the modified linked list and return.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Node class
class Node {
public:
    int data;
    Node* next;
 
    Node(int x)
    {
        this->data = x;
        this->next = NULL;
    }
};
 
// Function to reverse a Linked List
Node* reverseList(Node* head)
{
    Node *prev = NULL, *nextNode = NULL;
    while (head != NULL) {
 
        // Point to next node
        // of the current node
        nextNode = head->next;
 
        // Point next of current
        // to the previous node
        head->next = prev;
 
        prev = head;
 
        head = nextNode;
    }
    return prev;
}
 
// Function to modify a linked list
// such that it contains only the
// last occurrence of duplicate elements
Node* Remove_Dup_Keep_Last_Occurence(
    Node* head)
{
    // Make a dummy node
    Node* dummy = new Node(-1);
    dummy->next = head;
 
    // Reverse the given Linked List
    dummy->next = reverseList(dummy->next);
 
    // Stores duplicate elements
    unordered_set<int> visited;
 
    Node *currNode = dummy, *nextNode;
 
    // Iterate over the list
    while (currNode != NULL
           && currNode->next != NULL) {
 
        nextNode = currNode->next;
 
        // Check if data of the next node of the
        // current node is already visited or not
        if (visited.count(nextNode->data) != 0) {
 
            // Stores the duplicate pointer
            Node* duplicate = nextNode;
            currNode->next = nextNode->next;
 
            // Erase memory of duplicate pointer
            delete duplicate;
        }
        else {
 
            // Mark as visited to data of nextNode
            visited.insert(nextNode->data);
 
            // Go for the next node
            currNode = nextNode;
        }
    }
 
    // Reverse the modified linked list
    dummy->next = reverseList(dummy->next);
 
    return dummy->next;
}
 
// Function to print a Linked List
void print_Linked_List(Node* head)
{
    Node* curr = head;
    while (curr != NULL) {
        cout << curr->data << ' ';
        curr = curr->next;
    }
}
 
// Driver Code
int main()
{
 
    // Given Input
    Node* head = new Node(3);
    head->next = new Node(2);
    head->next->next = new Node(3);
    head->next->next->next = new Node(1);
    head->next->next->next->next = new Node(5);
    head->next->next->next->next->next = new Node(1);
    head->next->next->next->next->next->next = new Node(6);
 
    head = Remove_Dup_Keep_Last_Occurence(head);
 
    // Function Call
    print_Linked_List(head);
 
    return 0;
}


Java




// Java program for the above approach
import java.util.*;
 
class GFG
{
 
// Node class
static class Node {
    int data;
    Node next;
 
    Node(int x)
    {
        this.data = x;
        this.next = null;
    }
};
 
// Function to reverse a Linked List
static Node reverseList(Node head)
{
    Node prev = null, nextNode = null;
    while (head != null) {
 
        // Point to next node
        // of the current node
        nextNode = head.next;
 
        // Point next of current
        // to the previous node
        head.next = prev;
 
        prev = head;
 
        head = nextNode;
    }
    return prev;
}
 
// Function to modify a linked list
// such that it contains only the
// last occurrence of duplicate elements
static Node Remove_Dup_Keep_Last_Occurence(
    Node head)
{
    // Make a dummy node
    Node dummy = new Node(-1);
    dummy.next = head;
 
    // Reverse the given Linked List
    dummy.next = reverseList(dummy.next);
 
    // Stores duplicate elements
    HashSet<Integer> visited = new HashSet<Integer>();
 
    Node currNode = dummy;
    Node nextNode;
 
    // Iterate over the list
    while (currNode != null
           && currNode.next != null) {
 
        nextNode = currNode.next;
 
        // Check if data of the next node of the
        // current node is already visited or not
        if (visited.contains(nextNode.data)) {
 
            // Stores the duplicate pointer
            Node duplicate = nextNode;
            currNode.next = nextNode.next;
 
            // Erase memory of duplicate pointer
            duplicate=null;
        }
        else {
 
            // Mark as visited to data of nextNode
            visited.add(nextNode.data);
 
            // Go for the next node
            currNode = nextNode;
        }
    }
 
    // Reverse the modified linked list
    dummy.next = reverseList(dummy.next);
 
    return dummy.next;
}
 
// Function to print a Linked List
static void print_Linked_List(Node head)
{
    Node curr = head;
    while (curr != null) {
        System.out.print(curr.data +" ");
        curr = curr.next;
    }
}
 
// Driver Code
public static void main(String[] args)
{
 
    // Given Input
    Node head = new Node(3);
    head.next = new Node(2);
    head.next.next = new Node(3);
    head.next.next.next = new Node(1);
    head.next.next.next.next = new Node(5);
    head.next.next.next.next.next = new Node(1);
    head.next.next.next.next.next.next = new Node(6);
 
    head = Remove_Dup_Keep_Last_Occurence(head);
 
    // Function Call
    print_Linked_List(head);
 
}
}
 
// This code is contributed by shikhasingrajput


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
public class GFG {
 
    // Node class
public    class Node {
    public    int data;
    public    Node next;
 
    public    Node(int x) {
            this.data = x;
            this.next = null;
        }
    };
 
    // Function to reverse a Linked List
    static Node reverseList(Node head) {
        Node prev = null, nextNode = null;
        while (head != null) {
 
            // Point to next node
            // of the current node
            nextNode = head.next;
 
            // Point next of current
            // to the previous node
            head.next = prev;
 
            prev = head;
 
            head = nextNode;
        }
        return prev;
    }
 
    // Function to modify a linked list
    // such that it contains only the
    // last occurrence of duplicate elements
    static Node Remove_Dup_Keep_Last_Occurence(Node head)
    {
       
        // Make a dummy node
        Node dummy = new Node(-1);
        dummy.next = head;
 
        // Reverse the given Linked List
        dummy.next = reverseList(dummy.next);
 
        // Stores duplicate elements
        HashSet<int> visited = new HashSet<int>();
 
        Node currNode = dummy;
        Node nextNode;
 
        // Iterate over the list
        while (currNode != null && currNode.next != null) {
 
            nextNode = currNode.next;
 
            // Check if data of the next node of the
            // current node is already visited or not
            if (visited.Contains(nextNode.data)) {
 
                // Stores the duplicate pointer
                Node duplicate = nextNode;
                currNode.next = nextNode.next;
 
                // Erase memory of duplicate pointer
                duplicate = null;
            } else {
 
                // Mark as visited to data of nextNode
                visited.Add(nextNode.data);
 
                // Go for the next node
                currNode = nextNode;
            }
        }
 
        // Reverse the modified linked list
        dummy.next = reverseList(dummy.next);
 
        return dummy.next;
    }
 
    // Function to print a Linked List
    static void print_Linked_List(Node head) {
        Node curr = head;
        while (curr != null) {
            Console.Write(curr.data + " ");
            curr = curr.next;
        }
    }
 
    // Driver Code
    public static void Main(String[] args) {
 
        // Given Input
        Node head = new Node(3);
        head.next = new Node(2);
        head.next.next = new Node(3);
        head.next.next.next = new Node(1);
        head.next.next.next.next = new Node(5);
        head.next.next.next.next.next = new Node(1);
        head.next.next.next.next.next.next = new Node(6);
 
        head = Remove_Dup_Keep_Last_Occurence(head);
 
        // Function Call
        print_Linked_List(head);
 
    }
}
 
// This code is contributed by umadevi9616


Javascript




<script>
// javascript program for the above approach
 
    // Node class
class Node {
    constructor(val) {
        this.data = val;
        this.next = null;
    }
}
 
    // Function to reverse a Linked List
    function reverseList(head) {
    var prev = null, nextNode = null;
        while (head != null) {
 
            // Povar to next node
            // of the current node
            nextNode = head.next;
 
            // Povar next of current
            // to the previous node
            head.next = prev;
 
            prev = head;
 
            head = nextNode;
        }
        return prev;
    }
 
    // Function to modify a linked list
    // such that it contains only the
    // last occurrence of duplicate elements
    function Remove_Dup_Keep_Last_Occurence(head)
    {
     
        // Make a dummy node
        var dummy = new Node(-1);
        dummy.next = head;
 
        // Reverse the given Linked List
        dummy.next = reverseList(dummy.next);
 
        // Stores duplicate elements
        var visited = new Set();
 
        var currNode = dummy;
        var nextNode;
 
        // Iterate over the list
        while (currNode != null && currNode.next != null) {
 
            nextNode = currNode.next;
 
            // Check if data of the next node of the
            // current node is already visited or not
            if (visited.has(nextNode.data)) {
 
                // Stores the duplicate pointer
                var duplicate = nextNode;
                currNode.next = nextNode.next;
 
                // Erase memory of duplicate pointer
                duplicate = null;
            } else {
 
                // Mark as visited to data of nextNode
                visited.add(nextNode.data);
 
                // Go for the next node
                currNode = nextNode;
            }
        }
 
        // Reverse the modified linked list
        dummy.next = reverseList(dummy.next);
 
        return dummy.next;
    }
 
    // Function to prvar a Linked List
    function print_Linked_List(head) {
var curr = head;
        while (curr != null) {
            document.write(curr.data + " ");
            curr = curr.next;
        }
    }
 
    // Driver Code
     
 
        // Given Input
var head = new Node(3);
        head.next = new Node(2);
        head.next.next = new Node(3);
        head.next.next.next = new Node(1);
        head.next.next.next.next = new Node(5);
        head.next.next.next.next.next = new Node(1);
        head.next.next.next.next.next.next = new Node(6);
 
        head = Remove_Dup_Keep_Last_Occurence(head);
 
        // Function Call
        print_Linked_List(head);
 
// This code contributed by umadevi9616
</script>


 
 

Output: 

2 3 5 1 6

 

 

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

 




My Personal Notes arrow_drop_up
Recommended Articles
Page :