📜  在三个链表中查找公共元素

📅  最后修改于: 2021-10-27 07:09:32             🧑  作者: Mango

给定三个链表,找出三个链表中所有的公共元素。

例子:

Input :  
   10 15 20 25 12
   10 12 13 15 
   10 12 15 24 25 26
Output : 10 12 15 

Input :
   1 2 3 4 5
   1 2 3 4 6 9 8
   1 2 4 5 10
Output : 1 2 4

方法一:(简单)
使用三指针迭代给定的三个链表,如果有任何公共元素,则打印该元素。
上述解决方案的时间复杂度为 O(N*N*N)

方法二:(使用归并排序)
在这种方法中,我们首先对三个列表进行排序,然后遍历排序后的列表以获得交集。
以下是获得三个列表交集的步骤:
1) 使用归并排序对第一个链表进行排序。这一步需要 O(mLogm) 时间。有关此步骤的详细信息,请参阅此帖子。
2) 使用归并排序对第二个链表进行排序。这一步需要 O(nLogn) 时间。有关此步骤的详细信息,请参阅此帖子。
3) 使用归并排序对第三个链表进行排序。这一步需要 O(pLogp) 时间。有关此步骤的详细信息,请参阅此帖子。
3) 线性扫描三个排序列表得到交集。这一步需要 O(m + n + p) 时间。此步骤可以使用与此处讨论的排序数组算法相同的算法来实现。
该方法的时间复杂度为 O(mLogm + nLogn + plogp),优于方法 1 的时间复杂度。

方法3:(散列)
以下是使用散列获得三个列表交集的步骤:
1) 创建一个空的哈希表。遍历第一个链表并将哈希表中的所有元素频率标记为1。这一步需要 O(m) 时间。
2) 遍历第二个链表,如果哈希表中当前元素频率为1,则将其标记为2。这一步需要O(n)时间。
3) 迭代第三个链表,如果哈希表中当前元素频率为2,则标记为3。这一步需要O(p)时间。
4)现在再次迭代第一个链表以检查元素的频率。如果哈希表中存在频率为 3 的元素,则它将出现在三个链表的交集中。这一步需要 O(m) 时间。
该方法的时间复杂度为 O(m + n + p),优于方法 1 和方法 2 的时间复杂度。

下面是上述想法的实现。

C++
// C++ program to find common element
// in three unsorted linked list
#include 
#define max 1000000
using namespace std;
 
/* Link list node */
struct Node {
    int data;
    struct Node* next;
};
 
/* A utility function to insert a node at the
beginning of a linked list */
void push(struct Node** head_ref, int new_data)
{
    struct Node* new_node =
            (struct Node *)malloc(sizeof(struct Node));
    new_node->data = new_data;
    new_node->next = (*head_ref);
    (*head_ref) = new_node;
}
 
/* print the common element in between
given three linked list*/
void Common(struct Node* head1,
            struct Node* head2, struct Node* head3)
{
     
    // Creating empty hash table;
    unordered_map hash;
     
    struct Node* p = head1;
    while (p != NULL) {
         
        // set frequency by 1
        hash[p->data] = 1;
        p = p->next;
    }
     
    struct Node* q = head2;
    while (q != NULL) {
         
        // if the element is already exist in the
        // linked list set its frequency 2
        if (hash.find(q->data) != hash.end())
            hash[q->data] = 2;
        q = q->next;
    }
     
    struct Node* r = head3;
    while (r != NULL) {
        if (hash.find(r->data) != hash.end() &&
            hash[r->data] == 2)
         
        // if the element frquancy is 2 it means
        // its present in both the first and second
        // linked list set its frquancy 3
        hash[r->data] = 3;
        r = r->next;
    }
 
     
    for (auto x : hash) {
         
        // if current frequency is 3 its means
        // element is common in all the given
        // linked list
        if (x.second == 3)
            cout << x.first << " ";
    }
}
 
// Driver code
int main()
{
 
    // first list
    struct Node* head1 = NULL;
    push(&head1, 20);
    push(&head1, 5);
    push(&head1, 15);
    push(&head1, 10);
 
    // second list
    struct Node* head2 = NULL;
    push(&head2, 10);
    push(&head2, 20);
    push(&head2, 15);
    push(&head2, 8);
         
    // third list
    struct Node* head3 = NULL;
    push(&head3, 10);
    push(&head3, 2);
    push(&head3, 15);
    push(&head3, 20);
 
    Common(head1, head2, head3);
     
    return 0;
}


Java
// Java program to find common element
// in three unsorted linked list
import java.util.*;
 
class GFG
{
static int max = 1000000;
 
/* Link list node */
static class Node
{
    int data;
    Node next;
};
 
/* A utility function to insert a node
at the beginning of a linked list */
static Node push(Node head_ref,
                 int new_data)
{
    Node new_node = new Node();
    new_node.data = new_data;
    new_node.next = head_ref;
    head_ref = new_node;
    return head_ref;
}
 
/* print the common element in between
given three linked list*/
static void Common(Node head1,
                   Node head2,
                   Node head3)
{
     
    // Creating empty hash table;
    HashMap hash = new HashMap();
     
    Node p = head1;
    while (p != null)
    {
         
        // set frequency by 1
        hash. put(p.data, 1);
        p = p.next;
    }
     
    Node q = head2;
    while (q != null)
    {
         
        // if the element is already exist in the
        // linked list set its frequency 2
        if (hash.containsKey(q.data))
            hash. put(q.data, 2);
        q = q.next;
    }
     
    Node r = head3;
    while (r != null)
    {
        if (hash.containsKey(r.data)&&
            hash.get(r.data) == 2)
         
        // if the element frquancy is 2 it means
        // its present in both the first and second
        // linked list set its frquancy 3
        hash. put(r.data, 3);
        r = r.next;
    }
 
    for (Map.Entry x : hash.entrySet())
    {
         
        // if current frequency is 3 its means
        // element is common in all the given
        // linked list
        if (x.getValue() == 3)
            System.out.println(x.getKey() + " ");
    }
}
 
// Driver code
public static void main(String[] args)
{
     
    // first list
    Node head1 = null;
    head1 = push(head1, 20);
    head1 = push(head1, 5);
    head1 = push(head1, 15);
    head1 = push(head1, 10);
 
    // second list
    Node head2 = null;
    head2 = push(head2, 10);
    head2 = push(head2, 20);
    head2 = push(head2, 15);
    head2 = push(head2, 8);
         
    // third list
    Node head3 = null;
    head3 = push(head3, 10);
    head3 = push(head3, 2);
    head3 = push(head3, 15);
    head3 = push(head3, 20);
 
    Common(head1, head2, head3);
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 program to find common element
# in three unsorted linked list
max = 1000000
 
# Link list node
class Node:
     
    def __init__(self, data):
         
        self.data = data
        self.next = None
         
# A utility function to insert a node at the
# beginning of a linked list
def push( head_ref, new_data):
     
    new_node = Node(new_data)
    new_node.next = head_ref
    head_ref = new_node
    return head_ref
 
# Print the common element in between
# given three linked list
def Common(head1, head2, head3):
      
    # Creating empty hash table;
    hash = dict()
      
    p = head1
    while (p != None):
         
        # Set frequency by 1
        hash[p.data] = 1
        p = p.next
     
    q = head2
     
    while (q != None):
         
        # If the element is already exist in the
        # linked list set its frequency 2
        if (q.data in hash):
            hash[q.data] = 2
             
        q = q.next
 
    r = head3
     
    while (r != None):
        if (r.data in hash) and hash[r.data] == 2:
             
            # If the element frquancy is 2 it means
            # its present in both the first and second
            # linked list set its frquancy 3
            hash[r.data] = 3
             
        r = r.next
     
    for x in hash.keys():
         
        # If current frequency is 3 its means
        # element is common in all the given
        # linked list
        if (hash[x] == 3):
            print(x, end = ' ')
             
# Driver code
if __name__=='__main__':
  
    # First list
    head1 = None
    head1 = push(head1, 20)
    head1 = push(head1, 5)
    head1 = push(head1, 15)
    head1 = push(head1, 10)
  
    # Second list
    head2 = None
    head2 = push(head2, 10)
    head2 = push(head2, 20)
    head2 = push(head2, 15)
    head2 = push(head2, 8)
          
    # Third list
    head3 = None
    head3 = push(head3, 10)
    head3 = push(head3, 2)
    head3 = push(head3, 15)
    head3 = push(head3, 20)
  
    Common(head1, head2, head3)
      
# This code is contributed by rutvik_56


C#
// C# program to find common element
// in three unsorted linked list
using System;
using System.Collections.Generic;
 
class GFG
{
static int max = 1000000;
 
/* Link list node */
public class Node
{
    public int data;
    public Node next;
};
 
/* A utility function to insert a node
at the beginning of a linked list */
static Node push(Node head_ref,
                int new_data)
{
    Node new_node = new Node();
    new_node.data = new_data;
    new_node.next = head_ref;
    head_ref = new_node;
    return head_ref;
}
 
/* print the common element in between
given three linked list*/
static void Common(Node head1,
                Node head2,
                Node head3)
{
     
    // Creating empty hash table;
    Dictionary hash = new Dictionary();
     
    Node p = head1;
    while (p != null)
    {
         
        // set frequency by 1
        hash.Add(p.data, 1);
        p = p.next;
    }
     
    Node q = head2;
    while (q != null)
    {
         
        // if the element is already exist in the
        // linked list set its frequency 2
        if (hash.ContainsKey(q.data))
            hash[q.data] = 2;
        q = q.next;
    }
     
    Node r = head3;
    while (r != null)
    {
        if (hash.ContainsKey(r.data)&&
            hash[r.data] == 2)
         
        // if the element frquancy is 2 it means
        // its present in both the first and
        // second linked list set its frquancy 3
        hash[r.data] = 3;
        r = r.next;
    }
 
    foreach(KeyValuePair x in hash)
    {
         
        // if current frequency is 3 its means
        // element is common in all the given
        // linked list
        if (x.Value == 3)
            Console.Write(x.Key + " ");
    }
}
 
// Driver code
public static void Main(String[] args)
{
     
    // first list
    Node head1 = null;
    head1 = push(head1, 20);
    head1 = push(head1, 5);
    head1 = push(head1, 15);
    head1 = push(head1, 10);
 
    // second list
    Node head2 = null;
    head2 = push(head2, 10);
    head2 = push(head2, 20);
    head2 = push(head2, 15);
    head2 = push(head2, 8);
         
    // third list
    Node head3 = null;
    head3 = push(head3, 10);
    head3 = push(head3, 2);
    head3 = push(head3, 15);
    head3 = push(head3, 20);
 
    Common(head1, head2, head3);
}
}
 
// This code is contributed by Princi Singh


Javascript


输出:
10 15 20

时间复杂度:O(m + n + p)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程