📌  相关文章
📜  在三个排序的数组中查找共同的元素

📅  最后修改于: 2021-04-28 18:22:51             🧑  作者: Mango

给定三个以非降序排列的数组,请打印这些数组中的所有常见元素。

例子:

一种简单的解决方案是先找到两个数组的交集并将其存储在临时数组中,然后找到第三个数组与临时数组的交集。
此解决方案的时间复杂度为O(n1 + n2 + n3) ,其中n1,n2和n3分别是ar1 [],ar2 []和ar3 []的大小。
上面的解决方案需要额外的空间和两个循环,我们可以使用一个循环来查找公共元素,而无需额外的空间。这个想法类似于两个数组的交集。就像两个数组循环一样,我们运行一个循环并遍历三个数组。
令在ar1 []中遍历的当前元素为x,在ar2 []中遍历的元素为y,在ar3 []中遍历的元素为z。我们可以在循环中包含以下几种情况。

  • 如果x,y和z相同,我们可以简单地将它们中的任何一个打印为公共元素,并在所有三个数组中向前移动。
  • 否则,如果x
  • 否则,如果x> z和y> z),我们可以简单地在ar3 []中向前移动,因为z不能成为公共元素。

下图是上述方法的模拟:

下面是上述方法的实现:

C++
// C++ program to print common elements in three arrays
#include 
using namespace std;
 
// This function prints common elements in ar1
void findCommon(int ar1[], int ar2[], int ar3[], int n1, int n2, int n3)
{
    // Initialize starting indexes for ar1[], ar2[] and ar3[]
    int i = 0, j = 0, k = 0;
 
    // Iterate through three arrays while all arrays have elements
    while (i < n1 && j < n2 && k < n3)
    {
         // If x = y and y = z, print any of them and move ahead
         // in all arrays
         if (ar1[i] == ar2[j] && ar2[j] == ar3[k])
         {   cout << ar1[i] << " ";   i++; j++; k++; }
 
         // x < y
         else if (ar1[i] < ar2[j])
             i++;
 
         // y < z
         else if (ar2[j] < ar3[k])
             j++;
 
         // We reach here when x > y and z < y, i.e., z is smallest
         else
             k++;
    }
}
 
// Driver code
int main()
{
    int ar1[] = {1, 5, 10, 20, 40, 80};
    int ar2[] = {6, 7, 20, 80, 100};
    int ar3[] = {3, 4, 15, 20, 30, 70, 80, 120};
    int n1 = sizeof(ar1)/sizeof(ar1[0]);
    int n2 = sizeof(ar2)/sizeof(ar2[0]);
    int n3 = sizeof(ar3)/sizeof(ar3[0]);
 
    cout << "Common Elements are ";
    findCommon(ar1, ar2, ar3, n1, n2, n3);
    return 0;
}


Java
// Java program to find common elements in three arrays
class FindCommon
{
    // This function prints common elements in ar1
    void findCommon(int ar1[], int ar2[], int ar3[])
    {
        // Initialize starting indexes for ar1[], ar2[] and ar3[]
        int i = 0, j = 0, k = 0;
 
        // Iterate through three arrays while all arrays have elements
        while (i < ar1.length && j < ar2.length && k < ar3.length)
        {
             // If x = y and y = z, print any of them and move ahead
             // in all arrays
             if (ar1[i] == ar2[j] && ar2[j] == ar3[k])
             {   System.out.print(ar1[i]+" ");   i++; j++; k++; }
 
             // x < y
             else if (ar1[i] < ar2[j])
                 i++;
 
             // y < z
             else if (ar2[j] < ar3[k])
                 j++;
 
             // We reach here when x > y and z < y, i.e., z is smallest
             else
                 k++;
        }
    }
 
    // Driver code to test above
    public static void main(String args[])
    {
        FindCommon ob = new FindCommon();
 
        int ar1[] = {1, 5, 10, 20, 40, 80};
        int ar2[] = {6, 7, 20, 80, 100};
        int ar3[] = {3, 4, 15, 20, 30, 70, 80, 120};
 
        System.out.print("Common elements are ");
        ob.findCommon(ar1, ar2, ar3);
    }
}
 
/*This code is contributed by Rajat Mishra */


Python
# Python function to print common elements in three sorted arrays
def findCommon(ar1, ar2, ar3, n1, n2, n3):
     
    # Initialize starting indexes for ar1[], ar2[] and ar3[]
    i, j, k = 0, 0, 0
     
    # Iterate through three arrays while all arrays have elements   
    while (i < n1 and j < n2 and k< n3):
         
        # If x = y and y = z, print any of them and move ahead
        # in all arrays
        if (ar1[i] == ar2[j] and ar2[j] == ar3[k]):
            print ar1[i],
            i += 1
            j += 1
            k += 1
         
        # x < y   
        elif ar1[i] < ar2[j]:
            i += 1
             
        # y < z   
        elif ar2[j] < ar3[k]:
            j += 1
         
        # We reach here when x > y and z < y, i.e., z is smallest   
        else:
            k += 1
 
# Driver program to check above function
ar1 = [1, 5, 10, 20, 40, 80]
ar2 = [6, 7, 20, 80, 100]
ar3 = [3, 4, 15, 20, 30, 70, 80, 120]
n1 = len(ar1)
n2 = len(ar2)
n3 = len(ar3)
print "Common elements are",
findCommon(ar1, ar2, ar3, n1, n2, n3)
 
# This code is contributed by __Devesh Agrawal__


C#
// C# program to find common elements in
// three arrays
using System;
 
class GFG {
     
    // This function prints common element
    // s in ar1
    static void findCommon(int []ar1, int []ar2,
                                      int []ar3)
    {
         
        // Initialize starting indexes for
        // ar1[], ar2[] and ar3[]
        int i = 0, j = 0, k = 0;
 
        // Iterate through three arrays while
        // all arrays have elements
        while (i < ar1.Length && j < ar2.Length
                              && k < ar3.Length)
        {
             
            // If x = y and y = z, print any of
            // them and move ahead in all arrays
            if (ar1[i] == ar2[j] &&
                               ar2[j] == ar3[k])
            {
                Console.Write(ar1[i] + " ");
                i++;
                j++;
                k++;
            }
 
            // x < y
            else if (ar1[i] < ar2[j])
                i++;
 
            // y < z
            else if (ar2[j] < ar3[k])
                j++;
 
            // We reach here when x > y and
            // z < y, i.e., z is smallest
            else
                k++;
        }
    }
 
    // Driver code to test above
    public static void Main()
    {
         
        int []ar1 = {1, 5, 10, 20, 40, 80};
        int []ar2 = {6, 7, 20, 80, 100};
        int []ar3 = {3, 4, 15, 20, 30,
                             70, 80, 120};
 
        Console.Write("Common elements are ");
         
        findCommon(ar1, ar2, ar3);
    }
}
 
// This code is contributed by Sam007.


PHP
 y and
        // z < y, i.e., z is smallest
        else
            $k++;
    }
}
 
// Driver program to test above function
    $ar1 = array(1, 5, 10, 20, 40, 80);
    $ar2 = array(6, 7, 20, 80, 100);
    $ar3 = array(3, 4, 15, 20, 30, 70,
                                80, 120);
    $n1 = count($ar1);
    $n2 = count($ar2);
    $n3 = count($ar3);
 
    echo "Common Elements are ";
     
    findCommon($ar1, $ar2, $ar3,$n1, $n2, $n3);
     
// This code is contributed by anuj_67.
?>


Javascript


C++
// C++ program to print common
// elements in three arrays
#include 
using namespace std;
 
// This function prints
// common elements in ar1
void findCommon(int ar1[], int ar2[], int ar3[], int n1,
                int n2, int n3)
{
     
    // Initialize starting indexes
    // for ar1[], ar2[] and
    // ar3[]
    int i = 0, j = 0, k = 0;
 
    // Declare three variables prev1,
    // prev2, prev3 to track
    // previous element
    int prev1, prev2, prev3;
 
    // Initialize prev1, prev2,
    // prev3 with INT_MIN
    prev1 = prev2 = prev3 = INT_MIN;
 
    // Iterate through three arrays
    // while all arrays have
    // elements
    while (i < n1 && j < n2 && k < n3) {
       
        // If ar1[i] = prev1 and i < n1,
        // keep incrementing i
        while (ar1[i] == prev1 && i < n1)
            i++;
 
        // If ar2[j] = prev2 and j < n2,
        // keep incrementing j
        while (ar2[j] == prev2 && j < n2)
            j++;
 
        // If ar3[k] = prev3 and k < n3,
        // keep incrementing k
        while (ar3[k] == prev3 && k < n3)
            k++;
 
        // If x = y and y = z, print
        // any of them, update
        // prev1 prev2, prev3 and move
        //ahead in each array
        if (ar1[i] == ar2[j] && ar2[j] == ar3[k]) {
            cout << ar1[i] << " ";
            prev1 = ar1[i];
            prev2 = ar2[j];
            prev3 = ar3[k];
            i++;
            j++;
            k++;
        }
 
        // If x < y, update prev1
        // and increment i
        else if (ar1[i] < ar2[j]) {
            prev1 = ar1[i];
            i++;
        }
 
        // If y < z, update prev2
        // and increment j
        else if (ar2[j] < ar3[k]) {
            prev2 = ar2[j];
            j++;
        }
 
        // We reach here when x > y
        // and z < y, i.e., z is
        // smallest update prev3
        // and imcrement k
        else {
            prev3 = ar3[k];
            k++;
        }
    }
}
 
// Driver code
int main()
{
    int ar1[] = { 1, 5, 10, 20, 40, 80, 80 };
    int ar2[] = { 6, 7, 20, 80, 80, 100 };
    int ar3[] = { 3, 4, 15, 20, 30, 70, 80, 80, 120 };
    int n1 = sizeof(ar1) / sizeof(ar1[0]);
    int n2 = sizeof(ar2) / sizeof(ar2[0]);
    int n3 = sizeof(ar3) / sizeof(ar3[0]);
 
    cout << "Common Elements are ";
    findCommon(ar1, ar2, ar3, n1, n2, n3);
    return 0;
}


Javascript


Java
// Java implementation of the above approach
 
class GFG {
    public static void commonElements(int[] arr1,
                                      int[] arr2,
                                      int[] arr3, int n1,
                                      int n2, int n3)
    {
        // creating a max variable
        // for storing the maximum
        // value present in the all
        // the three array
        // this will be the size of
        // array for calculating the
        // frequency of each element
        // present in all the array
        int max = Integer.MIN_VALUE;
 
        // deleting duplicates in linear time
        // for arr1
        int res1 = 1;
        for (int i = 1; i < n1; i++)
        {
            max = Math.max(arr1[i], max);
            if (arr1[i] != arr1[res1 - 1])
            {
                arr1[res1] = arr1[i];
                res1++;
            }
        }
 
        // deleting duplicates in linear time
        // for arr2
        int res2 = 1;
        for (int i = 1; i < n2; i++)
        {
            max = Math.max(arr2[i], max);
            if (arr2[i] != arr2[res2 - 1])
            {
                arr2[res2] = arr2[i];
                res2++;
            }
        }
 
        // deleting duplicates in linear time
        // for arr3
        int res3 = 1;
        for (int i = 1; i < n3; i++)
        {
            max = Math.max(arr3[i], max);
            if (arr3[i] != arr3[res3 - 1])
            {
                arr3[res3] = arr3[i];
                res3++;
            }
        }
 
        // creating an array for finding frequency
        int[] freq = new int[max + 1];
 
        // calculating the frequency of
        // all the elements present in
        // all the array
        for (int i = 0; i < res1; i++)
            freq[arr1[i]]++;
        for (int i = 0; i < res2; i++)
            freq[arr2[i]]++;
        for (int i = 0; i < res3; i++)
            freq[arr3[i]]++;
 
        // iterating till max and
        // whenever the frequency of element
        // will be three we print that element
        for (int i = 0; i <= max; i++)
            if (freq[i] == 3)
                System.out.print(i + " ");
    }
   
    // Driver Code
    public static void main(String[] arg)
    {
 
        int arr1[] = { 1, 5, 10, 20, 40, 80 };
        int arr2[] = { 6, 7, 20, 80, 100 };
        int arr3[] = { 3, 4, 15, 20, 30, 70, 80, 120 };
 
        commonElements(arr1, arr2, arr3, 6, 5, 8);
    }
}


输出:

Common Elements are 20 80

上述解决方案的时间复杂度为O(n1 + n2 + n3) 。在最坏的情况下,最大大小的数组可能包含所有小元素,而中等大小的数组可能包含所有中间元素。

方法2

如果数组不包含重复值,则上面使用的方法效果很好,但是在重复数组元素的情况下它可能会失败。这可能导致单个公共元素被多次打印。

通过跟踪先前的元素,可以在不使用任何其他数据结构的情况下处理这些重复的条目。由于数组内部的元素以排序的方式排列,因此重复的元素不可能出现在随机位置。

让我们考虑在ar1 []中遍历的当前元素为x,在ar2 []中遍历的元素为ar,在ar3 []中遍历的当前元素为z,让变量prev1,prev2,prev3保持每个数组中最后遇到的元素的轨迹并用它们初始化INT_MIN。因此,对于我们在每个数组中访问的每个元素,我们都会检查以下内容。

  • 如果x = prev1,则在ar1 []中向前移动并重复该过程,直到x!= prev1。类似地,对ar2 []和ar3 []应用相同的内容。
  • 如果x,y和z相同,我们可以简单地将它们中的任何一个打印为公共元素,更新prev1,prev2和prev3并在所有三个数组中向前移动。
  • 否则,如果(x
  • 否则,如果(y
  • 否则,如果(x> z和y> z),我们将更新prev3,并在ar3 []中继续进行,因为z不能成为公共元素。

下面是上述方法的实现:

C++

// C++ program to print common
// elements in three arrays
#include 
using namespace std;
 
// This function prints
// common elements in ar1
void findCommon(int ar1[], int ar2[], int ar3[], int n1,
                int n2, int n3)
{
     
    // Initialize starting indexes
    // for ar1[], ar2[] and
    // ar3[]
    int i = 0, j = 0, k = 0;
 
    // Declare three variables prev1,
    // prev2, prev3 to track
    // previous element
    int prev1, prev2, prev3;
 
    // Initialize prev1, prev2,
    // prev3 with INT_MIN
    prev1 = prev2 = prev3 = INT_MIN;
 
    // Iterate through three arrays
    // while all arrays have
    // elements
    while (i < n1 && j < n2 && k < n3) {
       
        // If ar1[i] = prev1 and i < n1,
        // keep incrementing i
        while (ar1[i] == prev1 && i < n1)
            i++;
 
        // If ar2[j] = prev2 and j < n2,
        // keep incrementing j
        while (ar2[j] == prev2 && j < n2)
            j++;
 
        // If ar3[k] = prev3 and k < n3,
        // keep incrementing k
        while (ar3[k] == prev3 && k < n3)
            k++;
 
        // If x = y and y = z, print
        // any of them, update
        // prev1 prev2, prev3 and move
        //ahead in each array
        if (ar1[i] == ar2[j] && ar2[j] == ar3[k]) {
            cout << ar1[i] << " ";
            prev1 = ar1[i];
            prev2 = ar2[j];
            prev3 = ar3[k];
            i++;
            j++;
            k++;
        }
 
        // If x < y, update prev1
        // and increment i
        else if (ar1[i] < ar2[j]) {
            prev1 = ar1[i];
            i++;
        }
 
        // If y < z, update prev2
        // and increment j
        else if (ar2[j] < ar3[k]) {
            prev2 = ar2[j];
            j++;
        }
 
        // We reach here when x > y
        // and z < y, i.e., z is
        // smallest update prev3
        // and imcrement k
        else {
            prev3 = ar3[k];
            k++;
        }
    }
}
 
// Driver code
int main()
{
    int ar1[] = { 1, 5, 10, 20, 40, 80, 80 };
    int ar2[] = { 6, 7, 20, 80, 80, 100 };
    int ar3[] = { 3, 4, 15, 20, 30, 70, 80, 80, 120 };
    int n1 = sizeof(ar1) / sizeof(ar1[0]);
    int n2 = sizeof(ar2) / sizeof(ar2[0]);
    int n3 = sizeof(ar3) / sizeof(ar3[0]);
 
    cout << "Common Elements are ";
    findCommon(ar1, ar2, ar3, n1, n2, n3);
    return 0;
}

Java脚本


输出
Common Elements are 20 80 

上述方法的时间复杂度仍然为O(n1 + n2 + n3) ,空间复杂度也保持为O(1) ,不需要额外的空间和数据结构来处理重复的数组项。

方法3:

在这种方法中,我们将首先从每个数组中删除重复项,然后,我们将找到每个元素的频率,并打印频率等于3的元素。为了找到频率,我们可以使用地图,但是在这种情况下,我们将使用数组而不是地图。但是使用数组的问题是,我们找不到负数的频率,因此在下面给出的代码中,我们将把数组的每个元素都视为正数。

Java

// Java implementation of the above approach
 
class GFG {
    public static void commonElements(int[] arr1,
                                      int[] arr2,
                                      int[] arr3, int n1,
                                      int n2, int n3)
    {
        // creating a max variable
        // for storing the maximum
        // value present in the all
        // the three array
        // this will be the size of
        // array for calculating the
        // frequency of each element
        // present in all the array
        int max = Integer.MIN_VALUE;
 
        // deleting duplicates in linear time
        // for arr1
        int res1 = 1;
        for (int i = 1; i < n1; i++)
        {
            max = Math.max(arr1[i], max);
            if (arr1[i] != arr1[res1 - 1])
            {
                arr1[res1] = arr1[i];
                res1++;
            }
        }
 
        // deleting duplicates in linear time
        // for arr2
        int res2 = 1;
        for (int i = 1; i < n2; i++)
        {
            max = Math.max(arr2[i], max);
            if (arr2[i] != arr2[res2 - 1])
            {
                arr2[res2] = arr2[i];
                res2++;
            }
        }
 
        // deleting duplicates in linear time
        // for arr3
        int res3 = 1;
        for (int i = 1; i < n3; i++)
        {
            max = Math.max(arr3[i], max);
            if (arr3[i] != arr3[res3 - 1])
            {
                arr3[res3] = arr3[i];
                res3++;
            }
        }
 
        // creating an array for finding frequency
        int[] freq = new int[max + 1];
 
        // calculating the frequency of
        // all the elements present in
        // all the array
        for (int i = 0; i < res1; i++)
            freq[arr1[i]]++;
        for (int i = 0; i < res2; i++)
            freq[arr2[i]]++;
        for (int i = 0; i < res3; i++)
            freq[arr3[i]]++;
 
        // iterating till max and
        // whenever the frequency of element
        // will be three we print that element
        for (int i = 0; i <= max; i++)
            if (freq[i] == 3)
                System.out.print(i + " ");
    }
   
    // Driver Code
    public static void main(String[] arg)
    {
 
        int arr1[] = { 1, 5, 10, 20, 40, 80 };
        int arr2[] = { 6, 7, 20, 80, 100 };
        int arr3[] = { 3, 4, 15, 20, 30, 70, 80, 120 };
 
        commonElements(arr1, arr2, arr3, 6, 5, 8);
    }
}
输出
20 80