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

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.

Below is the implementation of the above approach.

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 triplets
int 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 elememt 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
    // mamimum 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 Code
int 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;
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find the
// number of triplets in array
// whose product is equal to M
import java.util.*;
  
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
    HashMap<Integer, Integer> frequency 
            = new HashMap<>(); 
  
    // put to store the unique triplets
    Set<String> st = new HashSet<String>(); 
  
    // count the number of times
    // every elememt 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
    // mamimum 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 addion,
                        // 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 Code
public 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
chevron_right

Output:
3

Time Complexity: O(N * log N)

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.





Striver(underscore)79 at Codechef and codeforces D

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Article Tags :
Practice Tags :