📌  相关文章
📜  在将第一个数组的每个元素与第二个数组相加后计算不同的元素

📅  最后修改于: 2021-09-16 10:59:13             🧑  作者: Mango

给定两个数组arr1[]arr2[] 。我们可以通过将数组arr1[]的每个元素添加到每个元素arr2[]来生成另一个数组arr3 [] 。任务是找到数组arr3[]中不同元素的计数。

例子:

朴素的方法:朴素的方法是从给定的两个数组中找到所有可能对的总和,并将该总和插入到数组arr3[] 中。打印数组arr3[]的所有元素的频率。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find Occurrence of each
// element from 1 to 2*MAX
void findCount(vector& Arr1,
               vector& Arr2)
{
    // Initialise MAX
    int MAX = max(*max_element(Arr1.begin(),
                               Arr1.end()),
                  *max_element(Arr2.begin(),
                               Arr2.end()));
 
    // Count vector to store count of
    // each element from 1 to 2*MAX
    vector Count(2 * MAX + 1, 0);
 
    // Size of Arr1 and Arr2
    int n = Arr1.size(), m = Arr2.size();
 
    // Find the elements of arr3[] and
    // increase count of element by 1
    for (int i = 0; i < n; i++) {
 
        for (int j = 0; j < m; j++) {
 
            int element = Arr1[i] + Arr2[j];
 
            Count[element]++;
        }
    }
 
    // Print the result
    for (int i = 1; i <= 2 * MAX; i++) {
 
        if (Count[i] > 0) {
            cout << i << "->"
                 << Count[i] << endl;
        }
    }
}
 
// Driver Code
int main()
{
    // Given arrays arr1[] and arr2[]
    vector arr1 = { 1, 2 };
    vector arr2 = { 1, 2, 1 };
 
    // Function Call
    findCount(arr1, arr2);
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG{
 
// Function to find Occurrence of each
// element from 1 to 2*MAX
static void findCount(int[] Arr1, int[]Arr2)
{
     
    // Initialise MAX
    int MAX = Math.max(Arrays.stream(Arr1).max().getAsInt(),
                       Arrays.stream(Arr2).max().getAsInt());
 
    // Count vector to store count of
    // each element from 1 to 2*MAX
    int[] Count = new int[2 * MAX + 1];
 
    // Size of Arr1 and Arr2
    int n = Arr1.length, m = Arr2.length;
 
    // Find the elements of arr3[] and
    // increase count of element by 1
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            int element = Arr1[i] + Arr2[j];
 
            Count[element]++;
        }
    }
 
    // Print the result
    for(int i = 1; i <= 2 * MAX; i++)
    {
        if (Count[i] > 0)
        {
            System.out.print(i + "->" +
                      Count[i] + "\n");
        }
    }
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given arrays arr1[] and arr2[]
    int[] arr1 = { 1, 2 };
    int[] arr2 = { 1, 2, 1 };
 
    // Function call
    findCount(arr1, arr2);
}
}
 
// This code is contributed by sapnasingh4991


Python3
# Python3 program for the above approach
 
# Function to find Occurrence of each
# element from 1 to 2*MAX
def findCount(Arr1, Arr2):
 
    # Initialise MAX
    MAX = max(max(Arr1), max(Arr2));
 
    # Count vector to store count of
    # each element from 1 to 2*MAX
    #Count = new int[2 * MAX + 1];
    Count = [0 for i in range(2 * MAX + 1)]
     
    # Size of Arr1 and Arr2
    n = len(Arr1);
    m = len(Arr2);
 
    # Find the elements of arr3 and
    # increase count of element by 1
    for i in range(n):
        for j in range(m):
            element = Arr1[i] + Arr2[j];
 
            Count[element]+=1;
         
    # Prthe result
    for i in range(1,2*MAX+1):
        if (Count[i] > 0):
            print(i , "->" , Count[i]);
         
# Driver Code
if __name__ == '__main__':
 
    # Given arrays arr1 and arr2
    arr1 = [1, 2 ];
    arr2 = [ 1, 2, 1 ];
 
    # Function call
    findCount(arr1, arr2);
 
# This code is contributed by Rohit_ranjan


C#
// C# program for the above approach
using System;
using System.Linq;
 
class GFG{
 
// Function to find Occurrence of each
// element from 1 to 2*MAX
static void findCount(int[] Arr1, int[]Arr2)
{
     
    // Initialise MAX
    int MAX = Math.Max(Arr1.Max(), Arr2.Max());
 
    // Count vector to store count of
    // each element from 1 to 2*MAX
    int[] Count = new int[2 * MAX + 1];
 
    // Size of Arr1 and Arr2
    int n = Arr1.Length, m = Arr2.Length;
 
    // Find the elements of arr3[] and
    // increase count of element by 1
    for(int i = 0; i < n; i++)
    {
        for(int j = 0; j < m; j++)
        {
            int element = Arr1[i] + Arr2[j];
            Count[element]++;
        }
    }
 
    // Print the result
    for(int i = 1; i <= 2 * MAX; i++)
    {
        if (Count[i] > 0)
        {
            Console.Write(i + "->" +
                   Count[i] + "\n");
        }
    }
}
 
// Driver Code
public static void Main(String[] args)
{
     
    // Given arrays arr1[] and arr2[]
    int[] arr1 = { 1, 2 };
    int[] arr2 = { 1, 2, 1 };
 
    // Function call
    findCount(arr1, arr2);
}
}
 
// This code is contributed by Princi Singh


Javascript


C++
// C++ program for the above approach
#include 
using namespace std;
using cd = complex;
 
// Value of PI need in FFT
const double PI = acos(-1);
 
// Function to implement the FFT
void fft(vector& a, bool invert)
{
    int n = a.size();
    if (n == 1)
        return;
 
    vector a0(n / 2), a1(n / 2);
    for (int i = 0; 2 * i < n; i++) {
        a0[i] = a[2 * i];
        a1[i] = a[2 * i + 1];
    }
 
    // Recursively find fft
    fft(a0, invert);
    fft(a1, invert);
 
    double ang = 2 * PI / n * (invert ? -1 : 1);
 
    cd w(1), wn(cos(ang), sin(ang));
 
    for (int i = 0; 2 * i < n; i++) {
        a[i] = a0[i] + w * a1[i];
        a[i + n / 2] = a0[i] - w * a1[i];
        if (invert) {
            a[i] /= 2;
            a[i + n / 2] /= 2;
        }
        w *= wn;
    }
}
 
// Function to multiply two polynomials
// A(x) and B(x) using FFT
vector multiply(vector const& a,
                     vector const& b)
{
    vector fa(a.begin(), a.end()),
        fb(b.begin(), b.end());
 
    int n = 1;
 
    while (n < a.size() + b.size()) {
        n <<= 1;
    }
 
    // Resize fa and fb
    fa.resize(n);
    fb.resize(n);
 
    // Assign initially false
    fft(fa, false);
    fft(fb, false);
 
    for (int i = 0; i < n; i++)
        fa[i] *= fb[i];
 
    fft(fa, true);
 
    // To store the result
    vector result(n);
 
    for (int i = 0; i < n; i++)
        result[i] = round(fa[i].real());
 
    // Return result
    return result;
}
 
// Function to find the Count of each
// element from 1 to 2*MAX
void findCount(vector& Arr1,
               vector& Arr2)
{
    // Initialise MAX
    int MAX = max(*max_element(Arr1.begin(),
                               Arr1.end()),
                  *max_element(Arr2.begin(),
                               Arr2.end()));
 
    int n = Arr1.size();
    int m = Arr2.size();
 
    // vector for Polynomial A(x) from Arr1
    vector A(MAX + 1);
 
    for (int i = 0; i < n; i++) {
        A[Arr1[i]]++;
    }
 
    // Vector for Polynomial B(x) from Arr2
    vector B(MAX + 1);
 
    for (int i = 0; i < m; i++) {
        B[Arr2[i]]++;
    }
 
    // Vector to store the result of
    // multiplication of A(x) and B(x)
    vector P;
 
    // Multiplying Arr1 and Arr2 and
    // storing in P is same as Count
    P = multiply(A, B);
 
    // Print the result
    for (int i = 1; i <= 2 * MAX; i++) {
        if (P[i] > 0) {
            cout << i << "->"
                 << P[i] << endl;
        }
    }
 
    cout << '\n';
}
 
// Driver Code
int main()
{
    // Given arrays arr1[] and arr2[]
    vector arr1 = { 1, 2 };
    vector arr2 = { 1, 2, 1 };
 
    // Function Call
    findCount(arr1, arr2);
}


输出:
2->2
3->3
4->1

时间复杂度: O(N 2 )
空间复杂度: O(N)

高效的解决方案:在 FFT(快速傅立叶变换)的帮助下,可以有效地完成给定的任务。以下是步骤:

  1. 考虑示例Arr1[] = {1, 2}Arr2[] = {1, 2, 1} 。令 Count 为频率数组,即 Count[i] 表示结果数组中 i 的频率。
  2. 当 Arr1[i] 与 Arr2[j] 相加时,我们增加 Count[s],其中 s = Arr1[i]+Arr2[j]。这类似于乘以多项式,因为功率增加了。
  3. 设 A(x) 是由 Arr1[] 表示的多项式。 Arr1 的元素表示 x 的幂,它们在 Arr1 中的计数是多项式中具有该幂的系数项。
  4. 对于每一项,x 的幂表示结果元素,系数表示其计数。
  5. 如果术语是k(x^i)
  6. 然后 Count[i] = k。这里 Count 与 P(x) 相同。
  7. 为了计算 P(x) 的值,我们可以简单地乘以 A(x) 和 B(x)。

多项式乘法的朴素方法需要 O(N 2 )。为了使乘法更快,我们可以使用 FFT(快速傅立叶变换)。

下面是上述方法的实现:

C++

// C++ program for the above approach
#include 
using namespace std;
using cd = complex;
 
// Value of PI need in FFT
const double PI = acos(-1);
 
// Function to implement the FFT
void fft(vector& a, bool invert)
{
    int n = a.size();
    if (n == 1)
        return;
 
    vector a0(n / 2), a1(n / 2);
    for (int i = 0; 2 * i < n; i++) {
        a0[i] = a[2 * i];
        a1[i] = a[2 * i + 1];
    }
 
    // Recursively find fft
    fft(a0, invert);
    fft(a1, invert);
 
    double ang = 2 * PI / n * (invert ? -1 : 1);
 
    cd w(1), wn(cos(ang), sin(ang));
 
    for (int i = 0; 2 * i < n; i++) {
        a[i] = a0[i] + w * a1[i];
        a[i + n / 2] = a0[i] - w * a1[i];
        if (invert) {
            a[i] /= 2;
            a[i + n / 2] /= 2;
        }
        w *= wn;
    }
}
 
// Function to multiply two polynomials
// A(x) and B(x) using FFT
vector multiply(vector const& a,
                     vector const& b)
{
    vector fa(a.begin(), a.end()),
        fb(b.begin(), b.end());
 
    int n = 1;
 
    while (n < a.size() + b.size()) {
        n <<= 1;
    }
 
    // Resize fa and fb
    fa.resize(n);
    fb.resize(n);
 
    // Assign initially false
    fft(fa, false);
    fft(fb, false);
 
    for (int i = 0; i < n; i++)
        fa[i] *= fb[i];
 
    fft(fa, true);
 
    // To store the result
    vector result(n);
 
    for (int i = 0; i < n; i++)
        result[i] = round(fa[i].real());
 
    // Return result
    return result;
}
 
// Function to find the Count of each
// element from 1 to 2*MAX
void findCount(vector& Arr1,
               vector& Arr2)
{
    // Initialise MAX
    int MAX = max(*max_element(Arr1.begin(),
                               Arr1.end()),
                  *max_element(Arr2.begin(),
                               Arr2.end()));
 
    int n = Arr1.size();
    int m = Arr2.size();
 
    // vector for Polynomial A(x) from Arr1
    vector A(MAX + 1);
 
    for (int i = 0; i < n; i++) {
        A[Arr1[i]]++;
    }
 
    // Vector for Polynomial B(x) from Arr2
    vector B(MAX + 1);
 
    for (int i = 0; i < m; i++) {
        B[Arr2[i]]++;
    }
 
    // Vector to store the result of
    // multiplication of A(x) and B(x)
    vector P;
 
    // Multiplying Arr1 and Arr2 and
    // storing in P is same as Count
    P = multiply(A, B);
 
    // Print the result
    for (int i = 1; i <= 2 * MAX; i++) {
        if (P[i] > 0) {
            cout << i << "->"
                 << P[i] << endl;
        }
    }
 
    cout << '\n';
}
 
// Driver Code
int main()
{
    // Given arrays arr1[] and arr2[]
    vector arr1 = { 1, 2 };
    vector arr2 = { 1, 2, 1 };
 
    // Function Call
    findCount(arr1, arr2);
}
输出:
2->2
3->3
4->1

时间复杂度: O(N*log N)
辅助空间: O(N)

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