Count distinct elements after adding each element of First Array with Second Array

Last Updated : 16 Mar, 2023

Given two arrays arr1[] and arr2[]. We can generate another array arr3[] by adding each element of the array arr1[] to each element arr2[]. The task is to find the count of distinct element in the array arr3[].

Examples:

Input: Arr1[] = {1, 2}, Arr2[] = {3, 4}, MAX = 4
Output:
4 -> 1
5 -> 2
6 -> 1
Explanation:
Here the third array will be Arr3[] = {1+3, 1+4, 2+3, 2+4} = {4, 5, 5, 6}

Input: Arr1[] = {1, 2}, Arr2[] = {1, 2, 1}, MAX = 2
Output:
2 -> 2
3 -> 3
4 -> 1
Explanation:
Here the third array is Arr3[] = {1+1, 1+2, 1+1, 2+1, 2+2, 2+1} = {2, 3, 2, 3, 4, 3}
Therefore Count of elements from 1 to 2*2 (4) are {0, 2, 3, 1}

Naive Approach: The naive approach is to find the sum of all possible pairs from the given two arrays and insert that sum into the array arr3[]. Print the frequency of all the elements of the array arr3[].

Below is the implementation of the above approach:

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<``int``>& Arr1,``               ``vector<``int``>& 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<``int``> 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<``int``> arr1 = { 1, 2 };``    ``vector<``int``> 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``;``        ` `    ``# Print the 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

 ``

Output:
```2->2
3->3
4->1```

Time Complexity: O(N2
Space Complexity: O(N)

Efficient Solution: The given task can be efficiently done with the help of FFT(Fast Fourier Transform). Below are the steps:

1. Consider the examples Arr1[] = {1, 2} and Arr2[] = {1, 2, 1}. Let Count be the frequency array i.e., Count[i] represents the frequency of i in resultant array.
2. When Arr1[i] is added to Arr2[j], we increment Count[s] where s = Arr1[i]+Arr2[j]. This is similar to multiplying polynomials as there power get added.
3. Let A(x) be the polynomial represented by Arr1[]. Elements of Arr1 represents power of x and their count in Arr1 are coefficients terms with that power in polynomial.
4. For each term, power of x represents the resulting element and the coefficient represents its count.
5. If term is
6. Then Count[i] = k. Here Count is same as P(x).
7. To calculate the value of P(x), we can simply multiply A(x) and B(x).

The Naive method of polynomial multiplication takes O(N2). To make the multiplication faster we can use FFT(Fast Fourier Transform).

Below is the implementation of the above approach:

C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;``using` `cd = complex<``double``>;` `// 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<``int``> multiply(vector<``int``> ``const``& a,``                     ``vector<``int``> ``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<``int``> 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<``int``>& Arr1,``               ``vector<``int``>& 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<``int``> A(MAX + 1);` `    ``for` `(``int` `i = 0; i < n; i++) {``        ``A[Arr1[i]]++;``    ``}` `    ``// Vector for Polynomial B(x) from Arr2``    ``vector<``int``> 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<``int``> 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<``int``> arr1 = { 1, 2 };``    ``vector<``int``> arr2 = { 1, 2, 1 };` `    ``// Function Call``    ``findCount(arr1, arr2);``}`

Java

 `import` `java.util.*;` `// Complex class definition``class` `Complex {` `  ``// Data members``  ``public` `double` `real, imag;` `  ``// Constructor``  ``public` `Complex(``double` `real, ``double` `imag)``  ``{``    ``this``.real = real;``    ``this``.imag = imag;``  ``}` `  ``// Method to add two Complex objects``  ``public` `Complex add(Complex other)``  ``{``    ``return` `new` `Complex(real + other.real,``                       ``imag + other.imag);``  ``}` `  ``// Method to subtract two Complex objects``  ``public` `Complex subtract(Complex other)``  ``{``    ``return` `new` `Complex(real - other.real,``                       ``imag - other.imag);``  ``}` `  ``// Method to multiply two Complex objects``  ``public` `Complex multiply(Complex other)``  ``{``    ``double` `re = real * other.real - imag * other.imag;``    ``double` `im = real * other.imag + imag * other.real;``    ``return` `new` `Complex(re, im);``  ``}` `  ``// Method to divide two Complex objects``  ``public` `Complex divide(Complex other)``  ``{``    ``double` `denom = other.real * other.real``      ``+ other.imag * other.imag;``    ``double` `re = (real * other.real + imag * other.imag)``      ``/ denom;``    ``double` `im = (imag * other.real - real * other.imag)``      ``/ denom;``    ``return` `new` `Complex(re, im);``  ``}``}` `class` `GFG {` `  ``// Function to implement the FFT``  ``public` `static` `void` `fft(ArrayList a,``                         ``boolean` `invert)``  ``{``    ``int` `n = a.size();``    ``if` `(n == ``1``) {``      ``return``;``    ``}` `    ``ArrayList a0 = ``new` `ArrayList<>();``    ``ArrayList a1 = ``new` `ArrayList<>();``    ``for` `(``int` `i = ``0``; ``2` `* i < n; i++) {``      ``a0.add(a.get(``2` `* i));``      ``a1.add(a.get(``2` `* i + ``1``));``    ``}` `    ``// Recursively find fft``    ``fft(a0, invert);``    ``fft(a1, invert);` `    ``double` `ang = ``2` `* Math.PI / n * (invert ? -``1` `: ``1``);` `    ``Complex w = ``new` `Complex(``1``, ``0``);``    ``Complex wn``      ``= ``new` `Complex(Math.cos(ang), Math.sin(ang));` `    ``for` `(``int` `i = ``0``; ``2` `* i < n; i++) {``      ``a.set(i, a0.get(i).add(w.multiply(a1.get(i))));``      ``a.set(i + n / ``2``, a0.get(i).subtract(``        ``w.multiply(a1.get(i))));``      ``if` `(invert) {``        ``a.set(i,``              ``a.get(i).divide(``new` `Complex(``2``, ``0``)));``        ``a.set(i + n / ``2``, a.get(i + n / ``2``).divide(``          ``new` `Complex(``2``, ``0``)));``      ``}``      ``w = w.multiply(wn);``    ``}``  ``}` `  ``// Function to multiply two polynomials``  ``// A(x) and B(x) using FFT``  ``public` `static` `ArrayList multiply(``int``[] a,``                                            ``int``[] b)``  ``{``    ``ArrayList fa = ``new` `ArrayList<>();``    ``ArrayList fb = ``new` `ArrayList<>();``    ``for` `(``int` `i = ``0``; i < a.length; i++) {``      ``fa.add(``new` `Complex(a[i], ``0``));``    ``}``    ``for` `(``int` `i = ``0``; i < b.length; i++) {``      ``fb.add(``new` `Complex(b[i], ``0``));``    ``}` `    ``int` `n = ``1``;` `    ``while` `(n < a.length + b.length) {``      ``n <<= ``1``;``    ``}` `    ``// Resize fa and fb``    ``while` `(fa.size() < n) {``      ``fa.add(``new` `Complex(``0``, ``0``));``    ``}``    ``while` `(fb.size() < n) {``      ``fb.add(``new` `Complex(``0``, ``0``));``    ``}` `    ``// Assign initially false``    ``fft(fa, ``false``);``    ``fft(fb, ``false``);` `    ``for` `(``int` `i = ``0``; i < n; i++) {``      ``fa.set(i, fa.get(i).multiply(fb.get(i)));``    ``}` `    ``fft(fa, ``true``);` `    ``// To store the result``    ``ArrayList result = ``new` `ArrayList<>();``    ``for` `(``int` `i = ``0``; i < n; i++) {``      ``result.add((``int``)Math.round(fa.get(i).real));``    ``}` `    ``// Return result``    ``return` `result;``  ``}` `  ``// Function to find the Count of each``  ``// element from 1 to 2*MAX``  ``public` `static` `void` `findCount(ArrayList arr1,``                               ``ArrayList arr2)``  ``{``    ``// Initialise MAX``    ``int` `MAX = Math.max(Collections.max(arr1),``                       ``Collections.max(arr2));` `    ``int` `n = arr1.size();``    ``int` `m = arr2.size();` `    ``// vector for Polynomial A(x) from Arr1``    ``int``[] A = ``new` `int``[MAX + ``1``];` `    ``for` `(``int` `i = ``0``; i < n; i++) {``      ``A[arr1.get(i)]++;``    ``}` `    ``// Vector for Polynomial B(x) from Arr2``    ``int``[] B = ``new` `int``[MAX + ``1``];` `    ``for` `(``int` `i = ``0``; i < m; i++) {``      ``B[arr2.get(i)]++;``    ``}` `    ``// Vector to store the result of``    ``// multiplication of A(x) and B(x)``    ``ArrayList P = multiply(A, B);` `    ``// Print the result``    ``for` `(``int` `i = ``1``; i <= ``2` `* MAX; i++) {``      ``if` `(P.get(i) > ``0``) {``        ``System.out.println(i + ``"->"` `+ P.get(i));``      ``}``    ``}` `    ``System.out.println();``  ``}` `  ``// Driver Code``  ``public` `static` `void` `main(String[] args)``  ``{``    ``// Given arrays arr1[] and arr2[]``    ``ArrayList arr1 = ``new` `ArrayList();``    ``arr1.add(``1``);``    ``arr1.add(``2``);` `    ``ArrayList arr2 = ``new` `ArrayList();``    ``arr2.add(``1``);``    ``arr2.add(``2``);``    ``arr2.add(``1``);` `    ``// Function Call``    ``findCount(arr1, arr2);``  ``}``}`

Python3

 `import` `math` `# Python3 program to implement the above approach` `# Value of PI need in FFT``PI ``=` `math.acos(``-``1``)` `# Function to implement the FFT``def` `fft(a, invert):``    ``n ``=` `len``(a)``    ``if` `(n ``=``=` `1``):``        ``return``    ` `    ``a0 ``=` `[``0``] ``*` `(n ``/``/` `2``)``    ``a1 ``=` `[``0``] ``*` `(n ``/``/` `2``)``    ` `    ``for` `i ``in` `range``(n ``/``/` `2``):``        ``a0[i] ``=` `a[``2` `*` `i]``        ``a1[i] ``=` `a[``2` `*` `i ``+` `1``]``    ` `    ``# Recursively find fft``    ``fft(a0, invert)``    ``fft(a1, invert)``    ` `    ``ang ``=` `2` `*` `PI ``/` `n ``*` `(``-``1` `if` `invert ``else` `1``)``    ` `    ``w ``=` `complex``(``1``)``    ``wn ``=` `complex``(math.cos(ang), math.sin(ang))``    ` `    ``for` `i ``in` `range``(n ``/``/` `2``):``        ``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``def` `multiply(a, b):``    ``fa ``=` `[``complex``(i, ``0``) ``for` `i ``in` `a]``    ``fb ``=` `[``complex``(i, ``0``) ``for` `i ``in` `b]` `    ``n ``=` `1` `    ``while` `(n < ``len``(a) ``+` `len``(b)):``        ``n <<``=` `1` `    ``# Resize fa and fb``    ``fa ``+``=` `[``complex``(``0``)] ``*` `(n ``-` `len``(fa))``    ``fb ``+``=` `[``complex``(``0``)] ``*` `(n ``-` `len``(fb))` `    ``# Assign initially false``    ``fft(fa, ``False``)``    ``fft(fb, ``False``)` `    ``for` `i ``in` `range``(n):``        ``fa[i] ``*``=` `fb[i]` `    ``fft(fa, ``True``)` `    ``# To store the result``    ``result ``=` `[``0``] ``*` `n` `    ``for` `i ``in` `range``(n):``        ``result[i] ``=` `round``(fa[i].real)` `    ``# Return result``    ``return` `result` `# Function to find the Count of each``# element from 1 to 2*MAX``def` `findCount(Arr1, Arr2):``    ``# Initialise MAX``    ``MAX` `=` `max``(``max``(Arr1), ``max``(Arr2))` `    ``n ``=` `len``(Arr1)``    ``m ``=` `len``(Arr2)` `    ``# vector for Polynomial A(x) from Arr1``    ``A ``=` `[``0``] ``*` `(``MAX` `+` `1``)` `    ``for` `i ``in` `range``(n):``        ``A[Arr1[i]] ``+``=` `1` `    ``# Vector for Polynomial B(x) from Arr2``    ``B ``=` `[``0``] ``*` `(``MAX` `+` `1``)` `    ``for` `i ``in` `range``(m):``        ``B[Arr2[i]] ``+``=` `1` `    ``# Vector to store the result of``    ``# multiplication of A(x) and B(x)``    ``P ``=` `[]` `    ``# Multiplying Arr1 and Arr2 and``    ``# storing in P is same as Count``    ``P ``=` `multiply(A, B)` `    ``# Print the result``    ``for` `i ``in` `range``(``1``, ``2` `*` `MAX` `+` `1``):``        ``if` `(P[i] > ``0``):``            ``print``(``str``(i) ``+` `"->"` `+` `str``(P[i]))` `    ``print``()` `# Driver Code``if` `__name__ ``=``=` `"__main__"``:``    ``# Given arrays arr1[] and arr2[]``    ``arr1 ``=``[``1``, ``2``]``    ``arr2 ``=` `[``1``, ``2``, ``1``]` `    ``# Function Call``    ``findCount(arr1, arr2)`

C#

 `using` `System;``using` `System.Linq;``using` `System.Collections.Generic;` `// Complex class definition``class` `Complex {``    ``// Data members``    ``public` `double` `real, imag;` `    ``// Constructor``    ``public` `Complex(``double` `real, ``double` `imag)``    ``{``        ``this``.real = real;``        ``this``.imag = imag;``    ``}` `    ``// Method to Add two Complex objects``    ``public` `Complex Add(Complex other)``    ``{``        ``return` `new` `Complex(real + other.real,``                           ``imag + other.imag);``    ``}` `    ``// Method to subtract two Complex objects``    ``public` `Complex Subtract(Complex other)``    ``{``        ``return` `new` `Complex(real - other.real,``                           ``imag - other.imag);``    ``}` `    ``// Method to multiply two Complex objects``    ``public` `Complex Multiply(Complex other)``    ``{``        ``double` `re = real * other.real - imag * other.imag;``        ``double` `im = real * other.imag + imag * other.real;``        ``return` `new` `Complex(re, im);``    ``}` `    ``// Method to divide two Complex objects``    ``public` `Complex Divide(Complex other)``    ``{``        ``double` `denom = other.real * other.real``                       ``+ other.imag * other.imag;``        ``double` `re = (real * other.real + imag * other.imag)``                    ``/ denom;``        ``double` `im = (imag * other.real - real * other.imag)``                    ``/ denom;``        ``return` `new` `Complex(re, im);``    ``}``}` `class` `GFG {``    ``// Function to implement the FFT``    ``public` `static` `void` `fft(List a, ``bool` `invert)``    ``{``        ``int` `n = a.Count;``        ``if` `(n == 1)``            ``return``;` `        ``List a0 = ``new` `List();``        ``List a1 = ``new` `List();``        ``for` `(``int` `i = 0; 2 * i < n; i++) {``            ``a0.Add(a[2 * i]);``            ``a1.Add(a[2 * i + 1]);``        ``}` `        ``// Recursively find fft``        ``fft(a0, invert);``        ``fft(a1, invert);` `        ``double` `ang = 2 * Math.PI / n * (invert ? -1 : 1);` `        ``Complex w = ``new` `Complex(1, 0);``        ``Complex wn``            ``= ``new` `Complex(Math.Cos(ang), Math.Sin(ang));` `        ``for` `(``int` `i = 0; 2 * i < n; i++) {``            ``a[i] = a0[i].Add(w.Multiply(a1[i]));``            ``a[i + n / 2]``                ``= a0[i].Subtract(w.Multiply(a1[i]));``            ``if` `(invert) {``                ``a[i] = a[i].Divide(``new` `Complex(2, 0));``                ``a[i + n / 2] = a[i + n / 2].Divide(``                    ``new` `Complex(2, 0));``            ``}``            ``w = w.Multiply(wn);``        ``}``    ``}` `    ``// Function to multiply two polynomials A(x) and B(x)``    ``// using FFT``    ``public` `static` `List<``int``> Multiply(``int``[] a, ``int``[] b)``    ``{``        ``List fa = ``new` `List();``        ``List fb = ``new` `List();``        ``for` `(``int` `i = 0; i < a.Length; i++)``            ``fa.Add(``new` `Complex(a[i], 0));``        ``for` `(``int` `i = 0; i < b.Length; i++)``            ``fb.Add(``new` `Complex(b[i], 0));` `        ``int` `n = 1;``        ``while` `(n < a.Length + b.Length)``            ``n <<= 1;` `        ``// Resize fa and fb``        ``while` `(fa.Count < n)``            ``fa.Add(``new` `Complex(0, 0));``        ``while` `(fb.Count < n)``            ``fb.Add(``new` `Complex(0, 0));` `        ``// Assign initially false``        ``fft(fa, ``false``);``        ``fft(fb, ``false``);` `        ``for` `(``int` `i = 0; i < n; i++) {``            ``fa[i] = fa[i].Multiply(fb[i]);``        ``}` `        ``fft(fa, ``true``);` `        ``// To store the result``        ``List<``int``> result = ``new` `List<``int``>();``        ``for` `(``int` `i = 0; i < n; i++) {``            ``result.Add((``int``)Math.Floor(fa[i].real));``        ``}` `        ``// Return result``        ``return` `result;``    ``}` `    ``// Function to find the Count of each``    ``// element from 1 to 2*MAX``    ``public` `static` `void` `FindCount(List<``int``> arr1,``                                 ``List<``int``> arr2)``    ``{``        ``// Initialise MAX``        ``int` `MAX = Math.Max(arr1.Max(), arr2.Max());` `        ``int` `n = arr1.Count;``        ``int` `m = arr2.Count;` `        ``// vector for Polynomial A(x) from Arr1``        ``int``[] A = ``new` `int``[MAX + 1];` `        ``for` `(``int` `i = 0; i < n; i++) {``            ``A[arr1[i]]++;``        ``}` `        ``// Vector for Polynomial B(x) from Arr2``        ``int``[] B = ``new` `int``[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)``        ``List<``int``> P = Multiply(A, B);` `        ``// Print the result``        ``for` `(``int` `i = 1; i <= 2 * MAX; i++) {``            ``if` `(P[i] > 0) {``                ``Console.WriteLine(i + ``"->"` `+ P[i]);``            ``}``        ``}` `        ``Console.WriteLine(``" "``);``    ``}` `    ``// Driver Code``    ``public` `static` `void` `Main(``string``[] args)``    ``{``        ``// Given arrays arr1[] and arr2[]``        ``List<``int``> arr1 = ``new` `List<``int``>();``        ``arr1.Add(1);``        ``arr1.Add(2);` `        ``List<``int``> arr2 = ``new` `List<``int``>();``        ``arr2.Add(1);``        ``arr2.Add(2);``        ``arr2.Add(1);` `        ``// Function Call``        ``FindCount(arr1, arr2);``    ``}``}`

Javascript

 `// Complex class definition``class Complex {` `    ``// Data members``    ``constructor(real, imag) {``        ``this``.real = real;``        ``this``.imag = imag;``    ``}` `    ``// Method to add two Complex objects``    ``add(other) {``        ``return` `new` `Complex(``this``.real + other.real,``            ``this``.imag + other.imag);``    ``}` `    ``// Method to subtract two Complex objects``    ``subtract(other) {``        ``return` `new` `Complex(``this``.real - other.real,``            ``this``.imag - other.imag);``    ``}` `    ``// Method to multiply two Complex objects``    ``multiply(other) {``        ``let re = ``this``.real * other.real - ``this``.imag * other.imag;``        ``let im = ``this``.real * other.imag + ``this``.imag * other.real;``        ``return` `new` `Complex(re, im);``    ``}` `    ``// Method to divide two Complex objects``    ``divide(other) {``        ``let denom = other.real * other.real +``            ``other.imag * other.imag;``        ``let re = (``this``.real * other.real + ``this``.imag * other.imag) /``            ``denom;``        ``let im = (``this``.imag * other.real - ``this``.real * other.imag) /``            ``denom;``        ``return` `new` `Complex(re, im);``    ``}``}`  `// Function to implement the FFT``function` `fft(a, invert) {``    ``let n = a.length;``    ``if` `(n == 1) {``        ``return``;``    ``}`  `    ``let a0 = [];``    ``let a1 = [];``    ``for` `(let i = 0; 2 * i < n; i++) {``        ``a0.push(a[2 * i]);``        ``a1.push(a[2 * i + 1]);``    ``}` `    ``// Recursively find fft``    ``fft(a0, invert);``    ``fft(a1, invert);` `    ``let ang = 2 * Math.PI / n * (invert ? -1 : 1);` `    ``let w = ``new` `Complex(1, 0);``    ``let wn = ``new` `Complex(Math.cos(ang), Math.sin(ang));` `    ``for` `(let i = 0; 2 * i < n; i++) {``        ``a[i] = a0[i].add(w.multiply(a1[i]));``        ``a[i + n / 2] = a0[i].subtract(``            ``w.multiply(a1[i]));``        ``if` `(invert) {``            ``a[i] = a[i].divide(``new` `Complex(2, 0));``            ``a[i + n / 2] = a[i + n / 2].divide(``                ``new` `Complex(2, 0));``        ``}``        ``w = w.multiply(wn);``    ``}` `}` `// Function to multiply two polynomials``// A(x) and B(x) using FFT``function` `multiply(a, b) {``    ``let fa = [];``    ``let fb = [];``    ``for` `(let i = 0; i < a.length; i++) {``        ``fa.push(``new` `Complex(a[i], 0));``    ``}``    ``for` `(let i = 0; i < b.length; i++) {``        ``fb.push(``new` `Complex(b[i], 0));``    ``}`  `    ``let n = 1;` `    ``while` `(n < a.length + b.length) {``        ``n <<= 1;``    ``}` `    ``// Resize fa and fb``    ``while` `(fa.length < n) {``        ``fa.push(``new` `Complex(0, 0));``    ``}``    ``while` `(fb.length < n) {``        ``fb.push(``new` `Complex(0, 0));``    ``}` `    ``// Assign initially false``    ``fft(fa, ``false``);``    ``fft(fb, ``false``);` `    ``for` `(let i = 0; i < n; i++) {``        ``fa[i] = fa[i].multiply(fb[i]);``    ``}` `    ``fft(fa, ``true``);` `    ``// To store the result``    ``let result = []``    ``for` `(``var` `i = 0; i < n; i++) {``        ``result.push(Math.floor(fa[i].real));``    ``}` `    ``// Return result``    ``return` `result;``}`  `// Function to find the Count of each``// element from 1 to 2*MAX``function` `findCount(arr1, arr2) {``    ``// Initialise MAX``    ``let MAX = Math.max(Math.max(...arr1),``        ``Math.max(...arr2));` `    ``let n = arr1.length;``    ``let m = arr2.length;` `    ``// vector for Polynomial A(x) from Arr1``    ``let A = ``new` `Array(MAX + 1).fill(0);` `    ``for` `(``var` `i = 0; i < n; i++) {``        ``A[arr1[i]]++;``    ``}` `    ``// Vector for Polynomial B(x) from Arr2``    ``let B = ``new` `Array(MAX + 1).fill(0);` `    ``for` `(``var` `i = 0; i < m; i++) {``        ``B[arr2[i]]++;``    ``}` `    ``// Vector to store the result of``    ``// multiplication of A(x) and B(x)``    ``let P = multiply(A, B);` `    ``// Print the result``    ``for` `(``var` `i = 1; i <= 2 * MAX; i++) {``        ``if` `(P[i] > 0) {``            ``console.log(i + ``"->"` `+ P[i]);``        ``}``    ``}` `    ``console.log(``" "``)``}` `// Driver Code` `// Given arrays arr1[] and arr2[]``let arr1 = []``arr1.push(1);``arr1.push(2);` `let arr2 = []``arr2.push(1);``arr2.push(2);``arr2.push(1);` `// Function Call``findCount(arr1, arr2);`

Output:
```2->2
3->3
4->1```

Time Complexity: O(N*log N)
Auxiliary Space: O(N)

Previous
Next