Count number of triplets with product equal to given number with duplicates allowed | Set-2 - GeeksforGeeks

12 Nov, 2021
Given an array of positive integers(may contain duplicates) and a number ‘m’, find the number of unordered triplets ((Ai, Aj, Ak) and (Aj, Ai, Ak) and other permutations are counted as one only) with product equal to ‘m’. 
Examples: 
Input: arr[] = { 1, 4, 6, 2, 3, 8}, M = 24 Output: 3 The triplets are {1, 4, 6} {1, 3, 8} {4, 2, 3}
Input: arr[] = { 0, 4, 6, 2, 3, 8}, M = 18 Output: 0 There are no triplets in this case 
A solution with O(N2) has been discussed in the previous post. In this post a better approach with lesser complexity has been discussed. 
Approach: The below algorithm is followed to solve the above problem.  
Use a hash-map to count the frequency of every element in the given array.
Declare a set which can store triplets, so that only unordered triplets are taken to count.
Iterate from 1 to sqrt(m) in a loop(let variable be i), since the maximum number by which M is divisible is sqrt(M) leaving out M.
Check if M is divisible by i or not and i is present in the array of integers or not, if it is, then again loop from 1 to M/i.(let the loop variable be j).
Again Check if M is divisible by j or not and j is present in the array of integers or not, if it is then check if the remaining number that is ( (M / i) / j) is present or not.
If it is present, then a triplet has been formed. To avoid duplicate triplets, insert them in the set in sorted order.
Check if the set the size increases after the insertion of triplet if it does then use combinatorics to find the number of triplets.
To find the number of triplets, the following conditions will be there. If all of the Ai, Aj and Ak are unique, then number of combinations will be the product of their frequencies.If all of them are same, then we can only choose three of them, hence the formula stands at .If any of the two are same(let Ai and Aj), the count will be * frequency[Ak]
If all of the Ai, Aj and Ak are unique, then number of combinations will be the product of their frequencies.If all of them are same, then we can only choose three of them, hence the formula stands at .If any of the two are same(let Ai and Aj), the count will be * frequency[Ak]
If all of the Ai, Aj and Ak are unique, then number of combinations will be the product of their frequencies.
If all of them are same, then we can only choose three of them, hence the formula stands at .
If any of the two are same(let Ai and Aj), the count will be * frequency[Ak]
Below is the implementation of the above approach.  
C++
Java
Python3
C#
Javascript
// C++ program to find the// number of triplets in array// whose product is equal to M#include <bits/stdc++.h>using namespace std; // Function to count the tripletsint countTriplets(int a[], int m, int n){     // hash-map to store the frequency of every number    unordered_map<int, int> frequency;     // set to store the unique triplets    set<pair<int, pair<int, int> > > st;     // count the number of times    // every element appears in a map    for (int i = 0; i < n; i++) {        frequency[a[i]] += 1;    }     // stores the answer    int ans = 0;     // iterate till sqrt(m) since tnum2t is the    // maximum number tnum2t can divide M except itself    for (int i = 1; i * i <= m; i++) {         // if divisible and present        if (m % i == 0 and frequency[i]) {             // remaining number after division            int num1 = m / i;             // iterate for the second number of the triplet            for (int j = 1; j * j <= num1; j++) {                 // if divisible and present                if (num1 % j == 0 and frequency[j]) {                     // remaining number after division                    int num2 = num1 / j;                     // if the third number is present in array                    if (frequency[num2]) {                         // a temp array to store the triplet                        int temp[] = { num2, i, j };                         // sort the triplets                        sort(temp, temp + 3);                         // get the size of set                        int setsize = st.size();                         // insert the triplet in ascending order                        st.insert({ temp[0], { temp[1], temp[2] } });                         // if the set size increases after insertion,                        //  it means a new triplet is found                        if (setsize != st.size()) {                             // if all the number in triplets are unique                            if (i != j and j != num2)                                ans += frequency[i] * frequency[j] * frequency[num2];                             // if Ai and Aj are same among triplets                            else if (i == j && j != num2)                                ans += (frequency[i] * (frequency[i] - 1) / 2)                                       * frequency[num2];                             // if Aj and Ak are same among triplets                            else if (j == num2 && j != i)                                ans += (frequency[j] * (frequency[j] - 1) / 2)                                       * frequency[i];                             // if three of them are                            // same among triplets                            else if (i == j and j == num2)                                ans += (frequency[i] * (frequency[i] - 1) * (frequency[i] - 2) / 6);                             // if Ai and Ak are same among triplets                            else                                ans += (frequency[i] * (frequency[i] - 1) / 2)                                       * frequency[j];                        }                    }                }            }        }    }     return ans;} // Driver Codeint main(){    int a[] = { 1, 4, 6, 2, 3, 8 };    int m = 24;    int n = sizeof(a) / sizeof(a[0]);     cout << countTriplets(a, m, n);     return 0;}
// Java program to find the// number of triplets in array// whose product is equal to Mimport java.util.*; class GFG{  // Function to count the tripletsstatic int countTriplets(int a[], int m, int n){     // hash-map to store    // the frequency of every number    HashMap<Integer, Integer> frequency            = new HashMap<>();     // put to store the unique triplets    Set<String> st = new HashSet<String>();     // count the number of times    // every element appears in a map    for (int i = 0; i < n; i++)    {        frequency.put(a[i],(frequency.get(a[i]) ==                null ? 1:(frequency.get(a[i]) + 1)));    }     // stores the answer    int ans = 0;     // iterate till sqrt(m) since tnum2t is the    // maximum number tnum2t can divide M except itself    for (int i = 1; i * i <= m; i++)    {         // if divisible && present        if (m % i == 0 && frequency.get(i)!=null)        {             // remaining number after division            int num1 = m / i;             // iterate for the second number of the triplet            for (int j = 1; j * j <= num1; j++)            {                 // if divisible && present                if (num1 % j == 0 && frequency.get(j) != null)                {                     // remaining number after division                    int num2 = num1 / j;                     // if the third number is present in array                    if (frequency.get(num2) != null)                    {                         // a temp array to store the triplet                        int temp[] = { num2, i, j };                         // sort the triplets                        Arrays.sort(temp);                         // get the size of put                        int setsize = st.size();                         // add the triplet in ascending order                        st.add(temp[0]+" "+ temp[1]+" " +temp[2] );                         // if the put size increases after addition,                        // it means a new triplet is found                        if (setsize != st.size())                        {                             // if all the number in triplets are unique                            if (i != j && j != num2)                                ans += frequency.get(i) *                                        frequency.get(j) *                                        frequency.get(num2);                             // if Ai && Aj are same among triplets                            else if (i == j && j != num2)                                ans += (frequency.get(i) *                                        (frequency.get(i) - 1) / 2)                                        * frequency.get(num2);                             // if Aj && Ak are same among triplets                            else if (j == num2 && j != i)                                ans += (frequency.get(j) *                                        (frequency.get(j) - 1) / 2)                                        * frequency.get(i);                             // if three of them are                            // same among triplets                            else if (i == j && j == num2)                                ans += (frequency.get(i) *                                        (frequency.get(i) - 1) *                                        (frequency.get(i) - 2) / 6);                             // if Ai && Ak are same among triplets                            else                                ans += (frequency.get(i) *                                        (frequency.get(i) - 1) / 2)                                        * frequency.get(j);                        }                    }                }            }        }    }    return ans;} // Driver Codepublic static void main(String args[]){    int a[] = { 1, 4, 6, 2, 3, 8 };    int m = 24;    int n = a.length;     System.out.println(countTriplets(a, m, n));}} // This code is contributed by Arnab Kundu
# Python3 program to find the# number of triplets in array# whose product is equal to Mimport math # Function to count the tripletsdef countTriplets(a, m, n):       # hash-map to store    # the frequency of every number    frequency = {}        # put to store the unique triplets    st = set({})        # count the number of times    # every element appears in a map    for i in range(n):        if a[i] in frequency:            frequency[a[i]] += 1        else:            frequency[a[i]] = 1        # stores the answer    ans = 0        # iterate till sqrt(m) since tnum2t is the    # maximum number tnum2t can divide M except itself    i = 1    while i * i <= m:               # if divisible && present        if (m % i == 0 and i in frequency):                       # remaining number after division            num1 = int(m / i)                # iterate for the second number of the triplet            j = 1            while j * j <= num1:                # if divisible && present                if (num1 % j == 0 and j in frequency):                    # remaining number after division                    num2 = math.floor(num1 / j)                        # if the third number is present in array                    if num2 in frequency:                        # a temp array to store the triplet                        temp = [ num2, i, j ]                            # sort the triplets                        temp.sort()                            # get the size of put                        setsize = len(st)                            # add the triplet in ascending order                        st.add(str(temp[0])+" "+ str(temp[1])+" " +str(temp[2]))                            # if the put size increases after addition,                        # it means a new triplet is found                        if setsize != len(st):                            # if all the number in                            # triplets are unique                            if (i != j and j != num2):                                ans += frequency[i] * frequency[j] * frequency[num2]                                # if Ai && Aj are same among triplets                            elif (i == j and j != num2):                                ans += (frequency[i] * (frequency[i] - 1) / 2) * frequency[num2]                                # if Aj && Ak are same among triplets                            elif (j == num2 and j != i):                                ans += (frequency[j] * (frequency[j] - 1) / 2) * frequency[i]                                # if three of them are                            # same among triplets                            elif (i == j and j == num2):                                ans += (frequency[i] * (frequency[i] - 1) * (frequency[i] - 2) / 6)                                # if Ai && Ak are same among triplets                            else:                                ans += (frequency[i] * (frequency[i] - 1) / 2) * frequency[j]                j += 1        i += 1    return int(ans) a=[1, 4, 6, 2, 3, 8 ]m = 24;n = len(a)print(countTriplets(a, m, n)) # This code is contributed by rameshtravel07.
// C# program to find the// number of triplets in array// whose product is equal to Musing System;using System.Collections.Generic;class GFG {         // Function to count the triplets    static int countTriplets(int[] a, int m, int n)    {              // hash-map to store        // the frequency of every number        Dictionary<int, int> frequency = new Dictionary<int, int>();              // put to store the unique triplets        HashSet<string> st = new HashSet<string>();              // count the number of times        // every element appears in a map        for (int i = 0; i < n; i++)        {            if(frequency.ContainsKey(a[i]))            {                frequency[a[i]] += 1;            }            else{                frequency[a[i]] = 1;            }        }              // stores the answer        int ans = 0;              // iterate till sqrt(m) since tnum2t is the        // maximum number tnum2t can divide M except itself        for (int i = 1; i * i <= m; i++)        {                  // if divisible && present            if (m % i == 0 && frequency.ContainsKey(i))            {                      // remaining number after division                int num1 = m / i;                      // iterate for the second number of the triplet                for (int j = 1; j * j <= num1; j++)                {                          // if divisible && present                    if (num1 % j == 0 && frequency.ContainsKey(j))                    {                              // remaining number after division                        int num2 = num1 / j;                              // if the third number is present in array                        if (frequency.ContainsKey(num2))                        {                                  // a temp array to store the triplet                            int[] temp = { num2, i, j };                                  // sort the triplets                            Array.Sort(temp);                                  // get the size of put                            int setsize = st.Count;                                  // add the triplet in ascending order                            st.Add(temp[0].ToString()+" "+ temp[1].ToString()+" " +temp[2].ToString());                                  // if the put size increases after addition,                            // it means a new triplet is found                            if (setsize != st.Count)                            {                                      // if all the number in triplets are unique                                if (i != j && j != num2)                                    ans += frequency[i] *                                            frequency[j] *                                            frequency[num2];                                      // if Ai && Aj are same among triplets                                else if (i == j && j != num2)                                    ans += (frequency[i] *                                            (frequency[i] - 1) / 2)                                            * frequency[num2];                                      // if Aj && Ak are same among triplets                                else if (j == num2 && j != i)                                    ans += (frequency[j] *                                            (frequency[j] - 1) / 2)                                            * frequency[i];                                      // if three of them are                                // same among triplets                                else if (i == j && j == num2)                                    ans += (frequency[i] *                                            (frequency[i] - 1) *                                            (frequency[i] - 2) / 6);                                      // if Ai && Ak are same among triplets                                else                                    ans += (frequency[i] *                                            (frequency[i] - 1) / 2)                                            * frequency[j];                            }                        }                    }                }            }        }        return ans;    }   // Driver code  static void Main() {    int[] a = { 1, 4, 6, 2, 3, 8 };    int m = 24;    int n = a.Length;      Console.Write(countTriplets(a, m, n));  }} // This code is contributed by decode2207.
<script> // JavaScript program to find the// number of triplets in array// whose product is equal to M // Function to count the tripletsfunction countTriplets(a,m,n){    // hash-map to store    // the frequency of every number    let frequency = new Map();       // put to store the unique triplets    let st = new Set();       // count the number of times    // every element appears in a map    for (let i = 0; i < n; i++)    {        frequency.set(a[i],(frequency.get(a[i]) ==                null ? 1:(frequency.get(a[i]) + 1)));    }       // stores the answer    let ans = 0;       // iterate till sqrt(m) since tnum2t is the    // maximum number tnum2t can divide M except itself    for (let i = 1; i * i <= m; i++)    {           // if divisible && present        if (m % i == 0 && frequency.get(i)!=null)        {               // remaining number after division            let num1 = m / i;               // iterate for the second number of the triplet            for (let j = 1; j * j <= num1; j++)            {                   // if divisible && present                if (num1 % j == 0 && frequency.get(j) != null)                {                       // remaining number after division                    let num2 = Math.floor(num1 / j);                       // if the third number is present in array                    if (frequency.get(num2) != null)                    {                           // a temp array to store the triplet                        let temp = [ num2, i, j ];                           // sort the triplets                        temp.sort(function(a,b){return a-b;});                           // get the size of put                        let setsize = st.size;                           // add the triplet in ascending order                        st.add(temp[0]+" "+ temp[1]+" " +temp[2] );                           // if the put size increases after addition,                        // it means a new triplet is found                        if (setsize != st.size)                        {                               // if all the number in                            // triplets are unique                            if (i != j && j != num2)                                ans += frequency.get(i) *                                        frequency.get(j) *                                        frequency.get(num2);                               // if Ai && Aj are same among triplets                            else if (i == j && j != num2)                                ans += (frequency.get(i) *                                        (frequency.get(i) - 1) / 2)                                        * frequency.get(num2);                               // if Aj && Ak are same among triplets                            else if (j == num2 && j != i)                                ans += (frequency.get(j) *                                        (frequency.get(j) - 1) / 2)                                        * frequency.get(i);                               // if three of them are                            // same among triplets                            else if (i == j && j == num2)                                ans += (frequency.get(i) *                                        (frequency.get(i) - 1) *                                        (frequency.get(i) - 2) / 6);                               // if Ai && Ak are same among triplets                            else                                ans += (frequency.get(i) *                                        (frequency.get(i) - 1) / 2)                                        * frequency.get(j);                        }                    }                }            }        }    }    return ans;} // Driver Codelet a=[1, 4, 6, 2, 3, 8 ];let m = 24;let n = a.length;document.write(countTriplets(a, m, n)); // This code is contributed by avanitrachhadiya2155 </script>
3
 
Time Complexity: O(N * log N) 
Akanksha_Rai
samagragupta
andrew1234
avanitrachhadiya2155
sagartomar9927
decode2207
rameshtravel07
kashishsoda
surindertarika1234
Codenation
cpp-pair
cpp-set
cpp-unordered_map
frequency-counting
Combinatorial
Codenation
Combinatorial
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Combinational Sum
Print all possible strings of length k that can be formed from a set of n characters
Count of subsets with sum equal to X
Python program to get all subsets of given size of a set
Print all distinct permutations of a given string with duplicates
Heap's Algorithm for generating permutations
Distinct permutations of the string | Set 2
Make all combinations of size k
Count Derangements (Permutation such that no element appears in its original position)
Print all subsets of given size of a set