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

📅  最后修改于: 2021-05-19 17:28:35             🧑  作者: Mango

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

天真的方法:天真的方法是从给定的两个数组中找到所有可能的对的和,并将该和插入到数组arr3 []中。打印数组arr3 []的所有元素的频率。
下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
  
// Function to find Occurence of each
// element from 1 to 2*MAX
void findCount(vector& Arr1,
               vector& Arr2)
{
    // Intialise 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 Occurence 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 Occurence 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 Occurence 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


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)
{
    // Intialise 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)
{
    // Intialise 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)