從未排序的連結串列中刪除重複項

jdon發表於2019-01-28

編寫一個removeduplicates()函式,該函式獲取一個列表並從列表中刪除所有重複的節點。列表未排序。

例如,如果連結串列是12->11->12->21->41->43->21,那麼removeUplicates()應該將連結串列轉換為12->11->21->41->43。

建議:請先在“實踐”中解決,然後再繼續解決問題。

方法1(使用兩個迴路)

這是使用兩個迴圈的簡單方法。外迴圈用於逐個選取元素,內迴圈將選取的元素與其餘元素進行比較。

感謝Gaurav Saxena在編寫此程式碼方面的幫助。

C++

/* Program to remove duplicates in an unsorted 
   linked list */
include<bits/stdc++.h> 
using namespace std; 
  
/* A linked list node */
struct Node 
{ 
    int data; 
    struct Node *next; 
}; 
  
// Utility function to create a new Node 
struct Node *newNode(int data) 
{ 
   Node *temp = new Node; 
   temp->data = data; 
   temp->next = NULL; 
   return temp; 
} 
  
/* Function to remove duplicates from a 
   unsorted linked list */
void removeDuplicates(struct Node *start) 
{ 
    struct Node *ptr1, *ptr2, *dup; 
    ptr1 = start; 
  
    /* Pick elements one by one */
    while (ptr1 != NULL && ptr1->next != NULL) 
    { 
        ptr2 = ptr1; 
  
        /* Compare the picked element with rest 
           of the elements */
        while (ptr2->next != NULL) 
        { 
            /* If duplicate then delete it */
            if (ptr1->data == ptr2->next->data) 
            { 
                /* sequence of steps is important here */
                dup = ptr2->next; 
                ptr2->next = ptr2->next->next; 
                delete(dup); 
            } 
            else /* This is tricky */
                ptr2 = ptr2->next; 
        } 
        ptr1 = ptr1->next; 
    } 
} 
  
/* Function to print nodes in a given linked list */
void printList(struct Node *node) 
{ 
    while (node != NULL) 
    { 
        printf("%d ", node->data); 
        node = node->next; 
    } 
} 
  
/* Druver program to test above function */
int main() 
{ 
    /* The constructed linked list is: 
     10->12->11->11->12->11->10*/
    struct Node *start = newNode(10); 
    start->next = newNode(12); 
    start->next->next = newNode(11); 
    start->next->next->next = newNode(11); 
    start->next->next->next->next = newNode(12); 
    start->next->next->next->next->next = 
                                    newNode(11); 
    start->next->next->next->next->next->next = 
                                    newNode(10); 
  
    printf("Linked list before removing duplicates "); 
    printList(start); 
  
    removeDuplicates(start); 
  
    printf("\nLinked list after removing duplicates "); 
    printList(start); 
  
    return 0; 
}



JAVA

// Java program to remove duplicates from unsorted  
// linked list 
  
class LinkedList { 
  
    static Node head; 
  
    static class Node { 
  
        int data; 
        Node next; 
  
        Node(int d) { 
            data = d; 
            next = null; 
        } 
    } 
  
    /* Function to remove duplicates from an 
       unsorted linked list */
    void remove_duplicates() { 
        Node ptr1 = null, ptr2 = null, dup = null; 
        ptr1 = head; 
  
        /* Pick elements one by one */
        while (ptr1 != null && ptr1.next != null) { 
            ptr2 = ptr1; 
  
            /* Compare the picked element with rest 
                of the elements */
            while (ptr2.next != null) { 
  
                /* If duplicate then delete it */
                if (ptr1.data == ptr2.next.data) { 
  
                    /* sequence of steps is important here */
                    dup = ptr2.next; 
                    ptr2.next = ptr2.next.next; 
                    System.gc(); 
                } else /* This is tricky */ { 
                    ptr2 = ptr2.next; 
                } 
            } 
            ptr1 = ptr1.next; 
        } 
    } 
  
    void printList(Node node) { 
        while (node != null) { 
            System.out.print(node.data + " "); 
            node = node.next; 
        } 
    } 
  
    public static void main(String args) { 
        LinkedList list = new LinkedList(); 
        list.head = new Node(10); 
        list.head.next = new Node(12); 
        list.head.next.next = new Node(11); 
        list.head.next.next.next = new Node(11); 
        list.head.next.next.next.next = new Node(12); 
        list.head.next.next.next.next.next = new Node(11); 
        list.head.next.next.next.next.next.next = new Node(10); 
  
        System.out.println("Linked List before removing duplicates : \n "); 
        list.printList(head); 
  
        list.remove_duplicates(); 
        System.out.println(""); 
        System.out.println("Linked List after removing duplicates : \n "); 
        list.printList(head); 
    } 
} 
// This code has been contributed by Mayank Jaiswal 



Output :
Linked list before removing duplicates:
 10 12 11 11 12 11 10 
Linked list after removing duplicates:
 10 12 11 


時間複雜度:  O(n^2)

方法2(使用排序)
通常,Merge Sort是最適合用於有效排序連結串列的排序演算法。
1)使用Merge Sort對元素進行排序。 我們很快就會寫一篇關於排序連結串列的帖子。O(nLogn)
2)使用用於刪除已排序的連結列表中的重複項的演算法,以線性時間刪除重複項。O(n)

請注意,此方法不保留元素的原始順序。

時間複雜度:O(nLogn)

方法3(使用雜湊)
我們從頭到尾遍歷連結列表。 對於每個新遇到的元素,我們檢查它是否在雜湊表中:如果是,我們將其刪除; 否則我們把它放在雜湊表中。

C++

/* Program to remove duplicates in an unsorted 
   linked list */
include<bits/stdc++.h> 
using namespace std; 
  
/* A linked list node */
struct Node 
{ 
    int data; 
    struct Node *next; 
}; 
  
// Utility function to create a new Node 
struct Node *newNode(int data) 
{ 
   Node *temp = new Node; 
   temp->data = data; 
   temp->next = NULL; 
   return temp; 
} 
  
/* Function to remove duplicates from a 
   unsorted linked list */
void removeDuplicates(struct Node *start) 
{ 
    // Hash to store seen values 
    unordered_set<int> seen; 
  
    /* Pick elements one by one */
    struct Node *curr = start; 
    struct Node *prev = NULL; 
    while (curr != NULL) 
    { 
        // If current value is seen before 
        if (seen.find(curr->data) != seen.end()) 
        { 
           prev->next = curr->next; 
           delete (curr); 
        } 
        else
        { 
           seen.insert(curr->data); 
           prev = curr; 
        } 
        curr = prev->next; 
    } 
} 
  
/* Function to print nodes in a given linked list */
void printList(struct Node *node) 
{ 
    while (node != NULL) 
    { 
        printf("%d ", node->data); 
        node = node->next; 
    } 
} 
  
/* Driver program to test above function */
int main() 
{ 
    /* The constructed linked list is: 
     10->12->11->11->12->11->10*/
    struct Node *start = newNode(10); 
    start->next = newNode(12); 
    start->next->next = newNode(11); 
    start->next->next->next = newNode(11); 
    start->next->next->next->next = newNode(12); 
    start->next->next->next->next->next = 
                                    newNode(11); 
    start->next->next->next->next->next->next = 
                                    newNode(10); 
  
    printf("Linked list before removing duplicates : \n"); 
    printList(start); 
  
    removeDuplicates(start); 
  
    printf("\nLinked list after removing duplicates : \n"); 
    printList(start); 
  
    return 0; 
} 


JAVA

// Java program to remove duplicates 
// from unsorted linkedlist 
  
import java.util.HashSet; 
  
public class removeDuplicates  
{ 
    static class node  
    { 
        int val; 
        node next; 
  
        public node(int val)  
        { 
            this.val = val; 
        } 
    } 
      
    /* Function to remove duplicates from a 
       unsorted linked list */
    static void removeDuplicate(node head)  
    { 
        // Hash to store seen values 
        HashSet<Integer> hs = new HashSet<>(); 
      
        /* Pick elements one by one */
        node current = head; 
        node prev = null; 
        while (current != null)  
        { 
            int curval = current.val; 
              
             // If current value is seen before 
            if (hs.contains(curval)) { 
                prev.next = current.next; 
            } else { 
                hs.add(curval); 
                prev = current; 
            } 
            current = current.next; 
        } 
  
    } 
      
    /* Function to print nodes in a given linked list */
    static void printList(node head)  
    { 
        while (head != null)  
        { 
            System.out.print(head.val + " "); 
            head = head.next; 
        } 
    } 
  
    public static void main(String args)  
    { 
        /* The constructed linked list is: 
         10->12->11->11->12->11->10*/
        node start = new node(10); 
        start.next = new node(12); 
        start.next.next = new node(11); 
        start.next.next.next = new node(11); 
        start.next.next.next.next = new node(12); 
        start.next.next.next.next.next = new node(11); 
        start.next.next.next.next.next.next = new node(10); 
  
        System.out.println("Linked list before removing duplicates :"); 
        printList(start); 
  
        removeDuplicate(start); 
  
        System.out.println("\nLinked list after removing duplicates :"); 
        printList(start); 
    } 
} 
  
// This code is contributed by Rishabh Mahrsee 



Output :
Linked list before removing duplicates:
 10 12 11 11 12 11 10 
Linked list after removing duplicates:
 10 12 11 


感謝bearwang建議這種方法。

時間複雜度:平均為O(n)(假設雜湊表訪問時間平均為O(1))。

相關文章