Given a sorted linked list, write a function to remove all the duplicate elements from the list, such that each element appears only once.

Example:

Input: 1 -> 1 -> 2 Output: 1 -> 2

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

Solution:

One approach to solve this problem is to traverse the linked list and keep track of the previous node and the current node. If the data of the previous node and the current node are the same, then we can remove the current node by skipping it.

Solution in Java:

While Java does have a built-in LinkedList class, it’s a good idea to understand how linked lists work and implement your own class. This can help you gain a better understanding of the data structure and make it easier to solve problems during an interview.

When implementing your own linked list class in Java, you’ll need to define a Node class to represent each node in the list. The Node class should have a value field to store the data and a next field to store a reference to the next node in the list.

You can then define a LinkedList class that has a head field to store a reference to the first node in the list. The LinkedList class should have methods to add and remove nodes from the list, as well as to traverse the list and perform any necessary operations.

class ListNode {
    int val;
    ListNode next;
    ListNode(int x) { val = x; }
}

public ListNode deleteDuplicates(ListNode head) {
    ListNode curr = head;
    while (curr != null && curr.next != null) {
        if (curr.val == curr.next.val) {
            curr.next = curr.next.next;
        } else {
            curr = curr.next;
        }
    }
    return head;
}

Solution in Ruby:

In Ruby, there is a built-in LinkedList class that you can use to implement a linked list. However, it’s important to understand how linked lists work and how to implement them yourself without relying on libraries. This will give you a better understanding of the underlying data structure and help you to write more efficient code.

class ListNode
  attr_accessor :val, :next
  def initialize(val = 0, _next = nil)
    @val = val
    @next = _next
  end
end

def delete_duplicates(head)
  curr = head
  while curr && curr.next
    if curr.val == curr.next.val
      curr.next = curr.next.next
    else
      curr = curr.next
    end
  end
  head
end

Solution in Python:

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

def delete_duplicates(head: ListNode) -> ListNode:
    curr = head
    while curr and curr.next:
        if curr.val == curr.next.val:
            curr.next = curr.next.next
        else:
            curr = curr.next
    return head

Solution in JavaScript:

function ListNode(val) {
  this.val = val;
  this.next = null;
}

var deleteDuplicates = function(head) {
  var curr = head;
  while (curr !== null && curr.next !== null) {
    if (curr.val === curr.next.val) {
      curr.next = curr.next.next;
    } else {
      curr = curr.next;
    }
  }
  return head;
};

In each of the solutions above, we define a ListNode class to represent each node in the linked list. We then define a function called deleteDuplicates which takes the head of the linked list as input.

See also  Check if a Linked List is a Palindrome

The function then iterates through the linked list using a while loop, keeping track of the current node (curr) and its next node. If the data of the current node and its next node are the same, we skip the next node by setting the next pointer of the current node to point to the node after the next node. Otherwise, we move on to the next node.

The time complexity of the above solution is O(n) where n is the number of nodes in the linked list. This is because we only need to traverse the linked list once, and each operation inside the loop is constant time.

An alternative solution to remove duplicates from a sorted linked list is to use a hash set to keep track of the values we have already seen. We can then iterate through the linked list and remove any nodes whose values are already in the hash set.

Pseudocode for the alternative solution:

function removeDuplicates(head):
    if head is null:
        return null
        
    seen = new set()
    curr = head
    prev = null
    
    while curr is not null:
        if curr.val in seen:
            prev.next = curr.next
        else:
            seen.add(curr.val)
            prev = curr
        curr = curr.next
        
    return head

In the code above, we first check if the linked list is empty and return null if it is. We then create an empty hash set called seen and initialize the current node curr to the head of the linked list and the previous node prev to null.

We then loop through the linked list using a while loop, checking if the value of the current node is already in the seen hash set. If it is, we skip the current node by setting the next pointer of the previous node to the node after the current node. Otherwise, we add the value of the current node to the seen hash set and set prev to curr. We then move on to the next node by setting curr to curr.next.

Finally, we return the head of the linked list which now contains only unique elements.

See also  Top 10 interview questions on linked lists

The time complexity of this solution is also O(n) where n is the number of nodes in the linked list, but it requires additional memory to store the hash set. However, it can be more efficient if the linked list is not sorted or if duplicates are more common, as the previous solution would require iterating through the entire list to remove duplicates.