📜  计算产品等于给定数量的三胞胎的数量,允许重复|套装2

📅  最后修改于: 2021-06-25 11:29:48             🧑  作者: Mango

给定一个正整数数组(可能包含重复项)和一个数字’m’,找到无序三元组((A i ,A j ,A k )和(A j ,A i ,A k )的数量,其他置换为仅计为1) ,其乘积等于’m’。

例子:

在上一篇文章中已经讨论了O(N 2 )的解决方案。在这篇文章中,已经讨论了一种具有较少复杂性的更好方法。

方法:下面的算法可以解决上述问题。

  • 使用哈希图计算给定数组中每个元素的频率。
  • 声明一个可以存储三元组的集合,这样就只考虑无序三元组。
  • 在循环中从1迭代到sqrt(m)(让变量为i),因为可以将M整除的最大数目是sqrt(M),而忽略了M。
  • 检查M是否可被i整除,并且i是否存在于整数数组中(如果存在),则再次从1循环到M / i(将循环变量设为j)。
  • 再次检查M是否可被j整除,并且j是否存在于整数数组中,如果是,则检查是否存在((M / i)/ j)的剩余数。
  • 如果存在,则已形成三元组。为避免重复的三元组,请按排序顺序将它们插入集合中。
  • 检查插入三元组后集合的大小是否增加(如果确实如此),然后使用组合函数查找三元组的数量。
  • 要查找三元组的数量,将存在以下条件。
    1. 如果所有的A i ,A j和A k都是唯一的,则组合的数量将为其频率的乘积。
    2. 如果它们全部相同,那么我们只能选择其中三个,因此公式为frequency \choose 3
    3. 如果两者相同(让Ai和Aj相等),则计数为frequency[Ai] \choose 2 *频率[A k ]

下面是上述方法的实现。

C++
// C++ program to find the
// number of triplets in array
// whose product is equal to M
#include 
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 frequency;
  
    // set to store the unique triplets
    set > > 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;
}


Java
// 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 frequency 
            = new HashMap<>(); 
  
    // put to store the unique triplets
    Set st = new HashSet(); 
  
    // 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


输出:
3

时间复杂度: O(N * log N)