Remove duplicates from an unsorted linked list

一世执手 提交于 2019-12-17 18:33:45

问题


import java.util.*;
/*
 *  Remove duplicates from an unsorted linked list
 */
public class LinkedListNode {  
    public int data;  
    public LinkedListNode next;  

    public LinkedListNode(int data) {  
        this.data = data;    
    }  
}

public class Task {
    public static void deleteDups(LinkedListNode head){
      Hashtable<Integer, Boolean> table=new Hashtable<Integer, Boolean>();
      LinkedListNode previous=null;
      //nth node is not null
      while(head!=null){
        //have duplicate
            if(table.containsKey(head.data)){
                            //skip duplicate
                previous.next=head.next;
            }else{
            //put the element into hashtable
            table.put(head.data,true);
            //move to the next element
            previous=head;
            }
      //iterate
      head=head.next;
      }
   }
   public static void main (String args[]){
       LinkedList<Integer> list=new LinkedList<Integer>();
       list.addLast(1);
       list.addLast(2);
       list.addLast(3);
       list.addLast(3);
       list.addLast(3);
       list.addLast(4);
       list.addLast(4);
       System.out.println(list);
       LinkedListNode head=new LinkedListNode(list.getFirst());
       Task.deleteDups(head);
       System.out.println(list);
   }
}

The result: [1, 2, 3, 3, 3, 4, 4] [1, 2, 3, 3, 3, 4, 4]

It does not eliminate the duplicates.

Why doesn't the method work?


回答1:


Iterate through the linked list, adding each element to a hash table. When we discover a duplicate element, we remove the element and continue iterating. We can do this all in one pass since we are using a linked list.

The following solution takes O(n) time, n is the number of element in the linked list.

public static void deleteDups (LinkedListNode n){
  Hashtable table = new Hashtable();
  LinkedListNode previous = null;
  while(n!=null){
      if(table.containsKey(n.data)){
          previous.next = n.next;
      } else {
          table.put(n.data, true);
          previous = n;
      }
      n = n.next;
  }
}



回答2:


  1. The solution you have provided does not modify the original list.
  2. To modify the original list and remove duplicates, we can iterate with two pointers. Current: which iterates through LinkedList, and runner which checks all subsequent nodes for duplicates.
  3. The code below runs in O(1) space but O(N square) time.

    public void deleteDups(LinkedListNode head){

    if(head == null)
        return;
    
    LinkedListNode currentNode = head;       
    while(currentNode!=null){
        LinkedListNode runner = currentNode;
        while(runner.next!=null){
            if(runner.next.data == currentNode.data)
                runner.next = runner.next.next;
            else
                runner = runner.next;
        }
        currentNode = currentNode.next;
    }
    

    }

Reference : Gayle laakmann mcdowell




回答3:


Here's two ways of doing this in java. the method used above works in O(n) but requires additional space. Where as the second version runs in O(n^2) but requires no additional space.

import java.util.Hashtable;

public class LinkedList {
LinkedListNode head;

public static void main(String args[]){
    LinkedList list = new LinkedList();
    list.addNode(1);
    list.addNode(1);
    list.addNode(1);
    list.addNode(2);
    list.addNode(3);
    list.addNode(2);

    list.print();
    list.deleteDupsNoStorage(list.head);
    System.out.println();
    list.print();
}

public void print(){
    LinkedListNode n = head;
    while(n!=null){
        System.out.print(n.data +" ");
        n = n.next;
    }
}

public void deleteDups(LinkedListNode n){
    Hashtable<Integer, Boolean> table = new Hashtable<Integer, Boolean>();
    LinkedListNode prev = null;

    while(n !=null){
        if(table.containsKey(new Integer(n.data))){
            prev.next = n.next;     //skip the previously stored references next node
        }else{
            table.put(new Integer(n.data) , true);
            prev = n;       //stores a reference to n
        }

        n = n.next;
    }
}

public void deleteDupsNoStorage(LinkedListNode n){
    LinkedListNode current = n;

    while(current!=null){
        LinkedListNode runner = current;
        while(runner.next!=null){
            if(runner.next.data == current.data){
                runner.next = runner.next.next;
            }else{
                runner = runner.next;
            }
        }
        current = current.next;
    }

}

public void addNode(int d){
    LinkedListNode n = new LinkedListNode(d);
    if(this.head==null){
        this.head = n;
    }else{
        n.next = head;
        head = n;
    }
}

private class LinkedListNode{
    LinkedListNode next;
    int data;

    public LinkedListNode(int d){
        this.data = d;
    }
}
}



回答4:


Ans is in C . first sorted link list sort() in nlog time and then deleted duplicate del_dip() .

node * partition(node *start)
{
    node *l1=start;
    node *temp1=NULL;
    node *temp2=NULL;
    if(start->next==NULL)
        return start;

    node * l2=f_b_split(start);
      if(l1->next!=NULL)
        temp1=partition(l1);
      if(l2->next!=NULL)
            temp2=partition(l2);

if(temp1==NULL || temp2==NULL)
    {
        if(temp1==NULL && temp2==NULL)
        temp1=s_m(l1,l2);

        else if(temp1==NULL)
        temp1=s_m(l1,temp2);

        else if(temp2==NULL)
        temp1=s_m(temp1,l2);
}
    else
            temp1=s_m(temp1,temp2);

    return temp1;
}

node * sort(node * start)
{
    node * temp=partition(start);
        return temp;
}

void del_dup(node * start)
{
  node * temp;
    start=sort(start);
    while(start!=NULL)
        {
        if(start->next!=NULL && start->data==start->next->data  )
            {
                temp=start->next;
                start->next=start->next->next;
                free(temp);
            continue;
            }
        start=start->next;
        }
}

void main()
 {
    del_dup(list1);
    print(list1);
} 



回答5:


Try this it is working for delete the duplicate elements from your linkedList

package com.loknath.lab;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;

public class Task {
    public static void main(String[] args) {

        LinkedList<Integer> list = new LinkedList<Integer>();
        list.addLast(1);
        list.addLast(2);
        list.addLast(3);
        list.addLast(3);
        list.addLast(3);
        list.addLast(4);
        list.addLast(4);
        deleteDups(list);
        System.out.println(list);
    }

    public static void deleteDups(LinkedList<Integer> list) {
        Set s = new HashSet<Integer>();
        s.addAll(list);
        list.clear();
        list.addAll(s);

    }
}



回答6:


Here is a very easy version.

LinkedList<Integer> a = new LinkedList<Integer>(){{
  add(1);
  add(1);
}}
Set<Integer> set = new HashSet<Integer>(a);
a = new LinkedList<Integer>(set);

LinkedList<Integer> a = new LinkedList<Integer>(){{
  add(1);
  add(1);
}}
Set<Integer> set = new HashSet<Integer>(a);
a = new LinkedList<Integer>(set);

Very concise. Isn't it?




回答7:


I think you can just use one iterator current to finish this problem 

public void compress(){
    ListNode current = front;
    HashSet<Integer> set = new HashSet<Integer>();
    set.add(current.data);
    while(current.next != null){
       if(set.contains(current.next.data)){
          current.next = current.next.next;         }
         else{
            set.add(current.next.data);
            current = current.next;
         }
      }

}




回答8:


You can use the following java method to remove duplicates:

1) With complexity of O(n^2)

public void removeDuplicate(Node head) {
    Node temp = head;
    Node duplicate = null;                //will point to duplicate node
    Node prev = null;                     //prev node to duplicate node
    while (temp != null) {                //iterate through all nodes       
        Node curr = temp;
        while (curr != null) {                     //compare each one by one
            /*in case of duplicate skip the node by using prev node*/
            if (curr.getData() == temp.getData() && temp != curr) {        
                duplicate = curr;
                prev.setNext(duplicate.getNext());
            }
            prev = curr;
            curr = curr.getNext();
        }
        temp = temp.getNext();
    }
}

Input:1=>2=>3=>5=>5=>1=>3=>

Output:1=>2=>3=>5=>

2)With complexity of O(n) using hash table.

public void removeDuplicateUsingMap(Node head) {
    Node temp = head;
    Map<Integer, Boolean> hash_map = new HashMap<Integer, Boolean>(); //create a hash map
    while (temp != null) {  
        if (hash_map.get(temp.getData()) == null) {  //if key is not set then set is false
            hash_map.put(temp.getData(), false);
        } else {                                   //if key is already there,then delete the node
            deleteNode(temp,head);
        }
        temp = temp.getNext();
    }

}

public void deleteNode(Node n, Node start) {
        Node temp = start;
        if (n == start) {
            start = null;
        } else {
            while (temp.getNext() != n) {
                temp = temp.getNext();
            }

            temp.setNext(n.getNext());

        }
    }

Input:1=>2=>3=>5=>5=>1=>3=>

Output:1=>2=>3=>5=>




回答9:


The first problem is that

LinkedListNode head=new LinkedListNode(list.getFirst());

does not actually initialize head with the contents of list. list.getFirst() simply returns the Integer 1, and head contains 1 as its only element. You would have to initialize head by looping through list in order to get all of the elements.

In addition, although

Task.deleteDups(head)

modifies head, this leaves list completely unchanged—there is no reason why the changes to head should propagate to list. Therefore, to check your method, you would have to loop down head and print out each element, rather than printing out list again.




回答10:


Try This.Its working. // Removing Duplicates in Linked List

import java.io.*;
import java.util.*;
import java.text.*;
class LinkedListNode{
    int data;
    LinkedListNode next=null;

    public LinkedListNode(int d){
        data=d;
    }
    void appendToTail(int d){
        LinkedListNode newnode = new LinkedListNode(d);
        LinkedListNode n=this;
        while(n.next!=null){
            n=n.next;
        }
        n.next=newnode;
    }

    void print(){
        LinkedListNode n=this;
        System.out.print("Linked List: ");
        while(n.next!=null){
            System.out.print(n.data+" -> ");
            n=n.next;
        }
        System.out.println(n.data);
    }
}
class LinkedList2_0
{
    public static void deletenode2(LinkedListNode head,int d){
        LinkedListNode n=head;
        // If It's head node
        if(n.data==d){
            head=n.next;
        }
        //If its other
        while(n.next!=null){
            if(n.next.data==d){
                n.next=n.next.next;
            }
            n=n.next;
        }
    }

    public static void removeDuplicateWithBuffer(LinkedListNode head){
        LinkedListNode n=head;
        LinkedListNode prev=null;
        Hashtable<Integer, Boolean> table = new Hashtable<Integer, Boolean>();
        while(n!=null){
            if(table.containsKey(n.data)){
                prev.next=n.next;
            }
            else{
                table.put(n.data,true);
                prev=n;
            }
            n=n.next;
        }
    }
    public static void removeDuplicateWithoutBuffer(LinkedListNode head){
        LinkedListNode currentNode=head;
        while(currentNode!=null){
            LinkedListNode runner=currentNode;
            while(runner.next!=null){
                if(runner.next.data==currentNode.data){
                    runner.next=runner.next.next;
                }
                else
                    runner=runner.next;
            }
            currentNode=currentNode.next;
        }
    }
    public static void main(String[] args) throws java.lang.Exception {
        LinkedListNode head=new LinkedListNode(1);
        head.appendToTail(1);
        head.appendToTail(3);
        head.appendToTail(2);
        head.appendToTail(3);
        head.appendToTail(4);
        head.appendToTail(5);
        head.print();

        System.out.print("After Delete: ");
        deletenode2(head,4);
        head.print();

        //System.out.print("After Removing Duplicates(with buffer): ");
        //removeDuplicateWithBuffer(head);
        //head.print();

        System.out.print("After Removing Duplicates(Without buffer): ");
        removeDuplicateWithoutBuffer(head);
        head.print();

    }
}



回答11:


here are a couple other solutions (slightly different from Cracking coding inerview, easier to read IMO).

public void deleteDupes(Node head) {

Node current = head;
while (current != null) {
    Node next = current.next;
    while (next != null) {
        if (current.data == next.data) {
            current.next = next.next;
            break;
        }

        next = next.next;
    }

    current = current.next;
}

}

public void deleteDupes(Node head) {
Node current = head;
while (current != null) {
    Node next = current.next;
    while (next != null) {
        if (current.data == next.data) {
            current.next = next.next;
            current = current.next;
            next = current.next;
        } else {
            next = next.next;
        }
    }

    current = current.next;
}

}




回答12:


It's simple way without HashSet or creation Node.

public String removeDuplicates(String str) {
    LinkedList<Character> chars = new LinkedList<Character>();

    for(Character c: str.toCharArray()){
        chars.add(c);
    }

    for (int i = 0; i < chars.size(); i++){
        for (int j = i+1; j < chars.size(); j++){
            if(chars.get(j) == chars.get(i)){
                chars.remove(j);
                j--;
            }
        }
    }

    return new String(chars.toString());
}

And to verify it:

@Test
public void verifyThatNoDuplicatesInLinkedList(){
    CodeDataStructures dataStructures = new CodeDataStructures();

    assertEquals("abcdefghjk", dataStructures.removeDuplicates("abcdefgabcdeaaaaaaaaafabcdeabcdefgabcdbbbbbbefabcdefghjkabcdefghjkghjkhjkabcdefghabcdefghjkjfghjkabcdefghjkghjkhjkabcdefghabcdefghjkj")
            .replace(",", "")
            .replace("]", "")
            .replace("[", "")
            .replace(" ", ""));
}



回答13:


LinkedList<Node> list = new LinkedList<Node>();

 for(int i=0; i<list.size(); i++){
        for(int j=0; j<list.size(); j++){
            if(list.get(i).data == list.get(j).data && i!=j){
                if(i<j){
                     list.remove(j);
                    if(list.get(j)!= null){
                         list.get(j-1).next = list.get(j);
                    }else{
                        list.get(j-1).next = null;
                    }

                }
                else{
                    if(i>j){
                        list.remove(i);
                        if(list.get(i) != null){
                            list.get(j).next = list.get(i);
                        }else{
                            list.get(j).next = null;
                        }

                    }
                }

            }

        }
    }



回答14:


/**
*
* Remove duplicates from an unsorted linked list.
*/
public class RemoveDuplicates {
    public static void main(String[] args) {
        LinkedList<String> list = new LinkedList<String>();
        list.add("Apple");
        list.add("Grape");
        list.add("Apple");
        HashSet<String> set = removeDuplicatesFromList(list);
        System.out.println("Removed duplicates" + set);
    }
    public static HashSet<String> removeDuplicatesFromList(LinkedList<String> list){
        HashSet<String> set = new LinkedHashSet<String>();
        set.addAll(list);
        return set;
    }
}



回答15:


Below code implements this without needing any temporary buffer. It starts with comparing first and second nodes, if not a match, it adds char at first node to second node then proceeds comparing all chars in second node to char at third node and so on. After comperison is complete, before leaving the node it clears everything that is added and restores its old value which resides at node.val.char(0)

F > FO > FOL > (match found, node.next = node.next.next) > (again match, discard it) > FOLW > ....

public void onlyUnique(){
        Node node = first;
        while(node.next != null){
            for(int i = 0 ; i < node.val.length(); i++){
                if(node.val.charAt(i) == node.next.val.charAt(0)){
                    node.next = node.next.next;
                }else{
                    if(node.next.next != null){ //no need to copy everything to the last element
                        node.next.val = node.next.val + node.val;
                    }
                    node.val = node.val.charAt(0)+ "";
                }
            }
            node = node.next;
        }
    }



回答16:


All the solutions given above looks optimised but most of them defines custom Node as a part of solution. Here is a simple and practical solution using Java's LinkedList and HashSet which does not confine to use the preexisting libraries and methods.

Time Complexity : O(n)

Space Complexity: O(n)

@SuppressWarnings({ "unchecked", "rawtypes" })
private static LinkedList<?> removeDupsUsingHashSet(LinkedList<?> list) {

    HashSet set = new HashSet<>();
    for (int i = 0; i < list.size();) {
        if (set.contains(list.get(i))) {
            list.remove(i);
            continue;
        } else {
            set.add(list.get(i));
            i++;
        }
    }
    return list;
}

This also preserves the list order.




回答17:


1.Fully Dynamic Approach 2.Remove Duplicates from LinkedList 3.LinkedList Dynamic Object based creation Thank you

import java.util.Scanner;
class Node{
    int data;
    Node next;
    public Node(int data)
    {
        this.data=data;
        this.next=null;
    }
}
class Solution
{
    public static Node insert(Node head,int data)
    {
    Node p=new Node(data);
    if(head==null)
    {
        head=p;
    }
    else if(head.next==null)
    {
        head.next=p;
    }
    else
    {
        Node start=head;
        while(start.next!=null)
        {
            start=start.next;   
        }
        start.next=p;
        return head;
        //System.out.println();
    }
    return head;    
    }
    public static void display(Node head)
    {
        Node start=head;
        while(start!=null)
        {
            System.out.print(start.data+" ");
            start=start.next;
        }

    }
    public static Node remove_duplicates(Node head)
    {
       if(head==null||head.next==null)
       {
           return head;
       }
       Node prev=head;
       Node p=head.next;

       while(p!=null)
       {
           if(p.data==prev.data)
           {
            prev.next=p.next;
            p=p.next;              
           }
           else{
               prev=p;
               p=p.next;   
           }
       }
       return head;
    }
    public static void main(String args[])
    {
        Scanner sc=new Scanner(System.in);
        Node head=null;
        int T=sc.nextInt();
        while(T-->0)
        {
            int ele=sc.nextInt();
            head=insert(head,ele);
        }
        head=remove_duplicates(head);
        display(head);  
    }
}

input: 5 1 1 2 3 3 output: 1 2 3



来源:https://stackoverflow.com/questions/17643790/remove-duplicates-from-an-unsorted-linked-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!