# Count ways to form minimum product triplets

Given an array of positive integers. We need to find how many triples of indices (i, j, k) (i < j < k), such that a[i] * a[j] * a[k] is minimum possible.

`Examples:Input : 5        1 3 2 3 4Output : 2The triplets are (1, 3, 2)and (1, 2, 3)Input : 5        2 2 2 2 2Output : 5In this example we choose three 2s out of five, and the number of ways to choose them is 5C3.Input : 6        1 3 3 1 3 2Output : 1There is only one way (1, 1, 2).`

Following cases arise in this problem.

1. All three minimum elements are same. For example {1, 1, 1, 1, 2, 3, 4}. The solution for such cases is nC3.
2. Two elements are same. For example {1, 2, 2, 2, 3} or {1, 1, 2, 2}. In this case, count of occurrences of first (or minimum element) cannot be more than 2. If minimum element appears two times, then answer is count of second element (We get to choose only 1 from all occurrences of second element. If minimum element appears once, the count is nC2.
3. All three elements are distinct. For example {1, 2, 3, 3, 5}. In this case, answer is count of occurrences of third element (or nC1).

We first sort the array in increasing order. Then count the frequency of 3 element of 3rd element from starting. Let the frequency be ‘count’. Following cases arise.

• If 3rd element is equal to the first element, no. of triples will be (count-2)*(count-1)*(count)/6, where count is the frequency of 3rd element.
• If 3rd element is equal to 2nd element, no. of triples will be (count-1)*(count)/2. Otherwise no. of triples will be value of count.

Implementation:

## C++

 `<``div` `id=``"highlighter_13225"` `class``=``"syntaxhighlighter nogutter  "``>
<``div` `class``=``"container"``><``div` `class``=``"line number1 index0 alt2"``>``// CPP program to count number of ways we can
// form triplets with minimum product.
#include
using namespace std;

// function to calculate number of triples
long long noOfTriples(long long arr[], int n)
{
// Sort the array
sort(arr, arr + n);

// Count occurrences of third element
long long count = 0;
for (long long i = 0; i < n; i++)
if (arr[i] == arr[2])
count++;

// If all three elements are same (minimum
// element appears at least 3 times). Answer
// is nC3.
if (arr[0] == arr[2])
return (count - 2) * (count - 1) * (count) / 6;

// If minimum element appears once.
else if (arr[1] == arr[2])
return (count - 1) * (count) / 2;

// Minimum two elements are distinct.
return count;
}

// Driver code
int main()
{
long long arr[] = { 1, 3, 3, 4 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << noOfTriples(arr, n);
return 0;
}
`

## Java

## Python3

## C#

## Javascript

## PHP

Output
```1

```

Time Complexity: O(n Log n)
Auxiliary Space: O(1)

The solution can be optimized by first finding minimum element and its frequency and if frequency is less than 3, then finding second minimum and its frequency. If overall frequency is less than 3, then finding third minimum and its frequency. Time complexity of this optimized solution would be O(n)

Approach Using Dp :

## C++

## Java

## Python3

 `def` `no_of_triples(arr, n):``    ``N ``=` `1005`  `# Define the value of N` `    ``# Sorting the array``    ``arr.sort()` `    ``# Initializing a 2D DP array with zeros``    ``dp ``=` `[[``0` `for` `_ ``in` `range``(N)] ``for` `_ ``in` `range``(n)]``    ``dp[``0``][arr[``0``]] ``=` `1` `    ``for` `i ``in` `range``(``1``, n):``        ``dp[i][arr[i]] ``=` `1``        ` `        ``# Filling in the DP array for values between arr[i-1] and arr[i]``        ``for` `j ``in` `range``(arr[i ``-` `1``] ``+` `1``, arr[i]):``            ``dp[i][j] ``=` `dp[i ``-` `1``][j]``        ` `        ``if` `arr[i] ``=``=` `arr[``1``]:``            ``# Handling special case when arr[i] equals arr[1]``            ``for` `j ``in` `range``(arr[``1``], arr[``2``] ``+` `1``):``                ``dp[i][arr[i]] ``+``=` `dp[i ``-` `1``][j] ``*` `(i ``-` `1``) ``*` `(i ``-` `2``) ``/``/` `2``        ``elif` `arr[i] ``=``=` `arr[``2``]:``            ``# Handling special case when arr[i] equals arr[2]``            ``dp[i][arr[i]] ``=` `dp[i ``-` `1``][arr[i]] ``*` `(i ``-` `1``) ``*` `(i ``-` `2``) ``/``/` `6``            ``for` `j ``in` `range``(arr[``2``], N):``                ``dp[i][j] ``+``=` `dp[i ``-` `1``][j]``        ``else``:``            ``# Filling in the DP array for values greater than arr[2]``            ``for` `j ``in` `range``(arr[``2``], N):``                ``dp[i][j] ``+``=` `dp[i ``-` `1``][j]``    ` `    ``ans ``=` `0``    ``# Summing up the values in the last row for indices between arr[0] and arr[2]``    ``for` `j ``in` `range``(arr[``0``], arr[``2``] ``+` `1``):``        ``ans ``+``=` `dp[n ``-` `1``][j]``    ` `    ``return` `ans` `if` `__name__ ``=``=` `"__main__"``:``    ``arr ``=` `[``1``, ``3``, ``3``, ``4``]``    ``n ``=` `len``(arr)``    ``print``(no_of_triples(arr, n))`  `# This code is contributed by rambabuguphka`

## C#

## Javascript

Output
```1

```

Time Complexity: O(n Log n)
Auxiliary Space: O(1)

Previous
Next