Given the head of a doubly linked list with its values sorted in non-decreasing order. Remove all duplicate occurrences of any value in the list so that only distinct values are present in the list.
Return the head of the modified linked list.
Input: head -> 1 <-> 1 <-> 3 <-> 3 <-> 4 <-> 5
Output: head -> 1 <-> 3 <-> 4 <-> 5
Explanation: head -> 1 <-> 1 <-> 3 <-> 3 <-> 4 <-> 5
The underlined nodes were deleted to get the desired result.
Input: head -> 1 <-> 1 <-> 1 <-> 1 <-> 1 <-> 2
Output: head -> 1 <-> 2
Explanation: head -> 1 <-> 1 <-> 1 <-> 1 <-> 1 <-> 2
The underlined nodes were deleted to get the desired result.
Input: head -> 1 <-> 2 <-> 3
#include <bits/stdc++.h>
using namespace std;
// Definition of Single Linked List
struct ListNode {
int val;
ListNode* next;
ListNode* prev;
ListNode() {
val = 0;
next = NULL;
prev = NULL;
}
ListNode(int data1) {
val = data1;
next = NULL;
prev = NULL;
}
ListNode(int data1, ListNode* next1, ListNode* prev1) {
val = data1;
next = next1;
prev = prev1;
}
};
class Solution {
public:
// To remove duplicates from a sorted doubly linked list
ListNode* removeDuplicates(ListNode* head) {
ListNode* temp = head;
// Traverse the list
while (temp != NULL && temp->next != NULL) {
ListNode* nextNode = temp->next;
// Remove all duplicate nodes
while (nextNode != NULL && nextNode->val == temp->val) {
// Store the duplicate node
ListNode* duplicate = nextNode;
// Move to the next node
nextNode = nextNode->next;
// Delete the duplicate node
delete duplicate;
}
/* Link the current node
to the next non-duplicate node*/
temp->next = nextNode;
/*Update previous pointer
of next non-duplicate node*/
if (nextNode != NULL) {
nextNode->prev = temp;
}
// Move to the next node
temp = temp->next;
}
return head;
}
};
// Function to print doubly linked list
void printList(ListNode* head) {
ListNode* temp = head;
while (temp != NULL) {
cout << temp->val << " ";
temp = temp->next;
}
cout << endl;
}
// Helper function to create a new node
ListNode* newNode(int data) {
ListNode* node = new ListNode(data);
return node;
}
int main() {
// Creating a sorted doubly linked list:
ListNode* head = newNode(1);
head->next = newNode(2);
head->next->prev = head;
head->next->next = newNode(2);
head->next->next->prev = head->next;
head->next->next->next = newNode(3);
head->next->next->next->prev = head->next->next;
head->next->next->next->next = newNode(4);
head->next->next->next->next->prev = head->next->next->next;
head->next->next->next->next->next = newNode(4);
head->next->next->next->next->next->prev = head->next->next->next->next;
head->next->next->next->next->next->next = newNode(5);
head->next->next->next->next->next->next->prev = head->next->next->next->next->next;
// Print original list
cout << "Original list: ";
printList(head);
// Remove duplicates
Solution sol;
head = sol.removeDuplicates(head);
// Print modified list
cout << "Modified list: ";
printList(head);
return 0;
}
import java.util.*;
// Definition of doubly linked list
class ListNode {
int val;
ListNode next;
ListNode prev;
ListNode() {
val = 0;
next = null;
prev = null;
}
ListNode(int data1) {
val = data1;
next = null;
prev = null;
}
ListNode(int data1, ListNode next1, ListNode prev1) {
val = data1;
next = next1;
prev = prev1;
}
}
class Solution {
// To remove duplicates from a sorted doubly linked list
public ListNode removeDuplicates(ListNode head) {
ListNode temp = head;
// Traverse the list
while (temp != null && temp.next != null) {
ListNode nextNode = temp.next;
// Remove all duplicate nodes
while (nextNode != null && nextNode.val == temp.val) {
// Store the duplicate node
ListNode duplicate = nextNode;
// Move to the next node
nextNode = nextNode.next;
// Delete the duplicate node
duplicate = null;
}
/* Link the current node
to the next non-duplicate node */
temp.next = nextNode;
/* Update previous pointer
of next non-duplicate node */
if (nextNode != null) {
nextNode.prev = temp;
}
// Move to the next node
temp = temp.next;
}
return head;
}
}
// Function to print doubly linked list
public class Main {
public static void printList(ListNode head) {
ListNode temp = head;
while (temp != null) {
System.out.print(temp.val + " ");
temp = temp.next;
}
System.out.println();
}
// Helper function to create a new node
public static ListNode newNode(int data) {
return new ListNode(data);
}
public static void main(String[] args) {
// Creating a sorted doubly linked list:
ListNode head = newNode(1);
head.next = newNode(2);
head.next.prev = head;
head.next.next = newNode(2);
head.next.next.prev = head.next;
head.next.next.next = newNode(3);
head.next.next.next.prev = head.next.next;
head.next.next.next.next = newNode(4);
head.next.next.next.next.prev = head.next.next.next;
head.next.next.next.next.next = newNode(4);
head.next.next.next.next.next.prev = head.next.next.next.next;
head.next.next.next.next.next.next = newNode(5);
head.next.next.next.next.next.next.prev = head.next.next.next.next.next;
// Print original list
System.out.print("Original list: ");
printList(head);
// Remove duplicates
Solution sol = new Solution();
head = sol.removeDuplicates(head);
// Print modified list
System.out.print("Modified list: ");
printList(head);
}
}
# Definition of doubly linked list
class ListNode:
def __init__(self, val=0, next=None, prev=None):
self.val = val
self.next = next
self.prev = prev
class Solution:
# To remove duplicates from a sorted doubly linked list
def removeDuplicates(self, head):
temp = head
# Traverse the list
while temp is not None and temp.next is not None:
nextNode = temp.next
# Remove all duplicate nodes
while nextNode is not None and nextNode.val == temp.val:
# Store the duplicate node
duplicate = nextNode
# Move to the next node
nextNode = nextNode.next
# Delete the duplicate node
del duplicate
# Link the current node to the next non-duplicate node
temp.next = nextNode
# Update previous pointer of next non-duplicate node
if nextNode is not None:
nextNode.prev = temp
# Move to the next node
temp = temp.next
return head
# Function to print doubly linked list
def printList(head):
temp = head
while temp is not None:
print(temp.val, end=" ")
temp = temp.next
print()
# Helper function to create a new node
def newNode(data):
return ListNode(data)
if __name__ == "__main__":
# Creating a sorted doubly linked list:
head = newNode(1)
head.next = newNode(2)
head.next.prev = head
head.next.next = newNode(2)
head.next.next.prev = head.next
head.next.next.next = newNode(3)
head.next.next.next.prev = head.next.next
head.next.next.next.next = newNode(4)
head.next.next.next.next.prev = head.next.next.next
head.next.next.next.next.next = newNode(4)
head.next.next.next.next.next.prev = head.next.next.next.next
head.next.next.next.next.next.next = newNode(5)
head.next.next.next.next.next.next.prev = head.next.next.next.next.next
# Print original list
print("Original list: ", end="")
printList(head)
# Remove duplicates
sol = Solution()
head = sol.removeDuplicates(head)
# Print modified list
print("Modified list: ", end="")
printList(head)
// Definition of doubly linked list
class ListNode {
constructor(val = 0, next = null, prev = null) {
this.val = val;
this.next = next;
this.prev = prev;
}
}
class Solution {
// To remove duplicates from a sorted doubly linked list
removeDuplicates(head) {
let temp = head;
// Traverse the list
while (temp !== null && temp.next !== null) {
let nextNode = temp.next;
// Remove all duplicate nodes
while (nextNode !== null && nextNode.val === temp.val) {
// Store the duplicate node
let duplicate = nextNode;
// Move to the next node
nextNode = nextNode.next;
// Delete the duplicate node
duplicate = null;
}
/* Link the current node
to the next non-duplicate node */
temp.next = nextNode;
/* Update previous pointer
of next non-duplicate node */
if (nextNode !== null) {
nextNode.prev = temp;
}
// Move to the next node
temp = temp.next;
}
return head;
}
}
// Function to print doubly linked list
function printList(head) {
let temp = head;
while (temp !== null) {
process.stdout.write(temp.val + " ");
temp = temp.next;
}
console.log();
}
// Helper function to create a new node
function newNode(data) {
return new ListNode(data);
}
(function() {
// Creating a sorted doubly linked list:
let head = newNode(1);
head.next = newNode(2);
head.next.prev = head;
head.next.next = newNode(2);
head.next.next.prev = head.next;
head.next.next.next = newNode(3);
head.next.next.next.prev = head.next.next;
head.next.next.next.next = newNode(4);
head.next.next.next.next.prev = head.next.next.next;
head.next.next.next.next.next = newNode(4);
head.next.next.next.next.next.prev = head.next.next.next.next;
head.next.next.next.next.next.next = newNode(5);
head.next.next.next.next.next.next.prev = head.next.next.next.next.next;
// Print original list
process.stdout.write("Original list: ");
printList(head);
// Remove duplicates
let sol = new Solution();
head = sol.removeDuplicates(head);
// Print modified list
process.stdout.write("Modified list: ");
printList(head);
})();
Q: How does this compare to removing duplicates from an unsorted DLL?
A: Sorted DLL (O(n)) → Duplicates are adjacent, allowing linear time removal. Unsorted DLL (O(n^2)) → Requires a hashmap (O(n) space) or nested traversal (O(n^2) time).
Q: What if we needed to keep one occurrence of each duplicate?
A: Instead of removing all duplicates, retain only the first.
Q: How would this work in a singly linked list?
A: The logic remains the same, but we lose prev access, requiring additional traversal.