Skip to content
Related Articles

Related Articles

Improve Article

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

  • Difficulty Level : Hard
  • Last Updated : 26 Jul, 2021

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:  

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

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 <bits/stdc++.h>
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;
         
    # 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




<script>
// JavaScript program for the above approach
 
// Function to find Occurrence of each
// element from 1 to 2*MAX
function findCount(Arr1, Arr2)
{
       
    // Initialise MAX
    let MAX = Math.max(Math.max(...Arr1),
                       Math.max(...Arr2));
   
    // Count vector to store count of
    // each element from 1 to 2*MAX
    let Count = Array.from({length: 2 * MAX + 1}, (_, i) => 0);
   
    // Size of Arr1 and Arr2
    let n = Arr1.length, m = Arr2.length;
   
    // Find the elements of arr3[] and
    // increase count of element by 1
    for(let i = 0; i < n; i++)
    {
        for(let j = 0; j < m; j++)
        {
            let element = Arr1[i] + Arr2[j];
   
            Count[element]++;
        }
    }
   
    // Prlet the result
    for(let i = 1; i <= 2 * MAX; i++)
    {
        if (Count[i] > 0)
        {
            document.write(i + "->" +
                      Count[i] + "<br/>");
        }
    }
}
       
// Driver Code
     
    // Given arrays arr1[] and arr2[]
    let arr1 = [ 1, 2 ];
    let arr2 = [ 1, 2, 1 ];
   
    // Function call
    findCount(arr1, arr2);
               
</script>
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 isk(x^i)
  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 <bits/stdc++.h>
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<cd>& a, bool invert)
{
    int n = a.size();
    if (n == 1)
        return;
 
    vector<cd> 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<cd> 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);
}
Output: 
2->2
3->3
4->1

 

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




My Personal Notes arrow_drop_up
Recommended Articles
Page :