# Find the Number of Maximum Product Quadruples

• Difficulty Level : Medium
• Last Updated : 02 Jul, 2022

Given an array of N positive elements, find the number of quadruples, (i, j, k, m) such that i < j < k < m such that the product aiajakam is the maximum possible.

Examples:

```Input : N = 7, arr = {1, 2, 3, 3, 3, 3, 5}
Output : 4
Explanation
The maximum quadruple product possible is 135, which can be
achieved by the following quadruples {i, j, k, m} such that aiajakam = 135:
1) a3a4a5a7
2) a3a4a6a7
3) a4a5a6a7
4) a3a5a6a7

Input : N = 4, arr = {1, 5, 2, 1}
Output : 1
Explanation
The maximum quadruple product possible is 10, which can be
achieved by the following quadruple {1, 2, 3, 4} as a1a2a3a4 = 10```

Brute Force: O(n4)
Generate all possible quadruple and count the quadruples, giving the maximum product.

Optimized Solution
It is easy to see that the product of the four largest numbers would be the maximum. So, the problem can now be reduced to finding the number of ways of selecting the four largest elements. To do so, we maintain a frequency array that stores the frequency of each element of the array.
Suppose the largest element is X with frequency FX, then if the frequency of this element is >= 4, it is best suited to select the four elements as X, X, X, as that, given a maximum product and the number of ways to do so is FX C 4
and if the frequency is less than 4, the number of ways to select this is 1 and now the required number of elements is 4 – FX. For the second element, say Y, the number of ways are: FX C remaining_choices. Remaining choices denotes the number of additional elements we need to select after selecting the first element. If at any time, the remaining_choices = 0, it means the quadruples are selected, so we can stop the algorithm.

## C++

 `// CPP program to find the number of Quadruples``// having maximum product``#include ``using` `namespace` `std;` `// Returns the number of ways to select r objects``// out of available n choices``int` `NCR(``int` `n, ``int` `r)``{``    ``int` `numerator = 1;``    ``int` `denominator = 1;` `    ``// ncr = (n * (n - 1) * (n - 2) * .....``    ``// ... (n - r + 1)) / (r * (r - 1) * ... * 1)``    ``while` `(r > 0) {``        ``numerator *= n;``        ``denominator *= r;``        ``n--;``        ``r--;``    ``}` `    ``return` `(numerator / denominator);``}` `// Returns the number of quadruples having maximum product``int` `findWays(``int` `arr[], ``int` `n)``{``    ``// stores the frequency of each element``    ``map<``int``, ``int``> count;` `    ``if` `(n < 4)``        ``return` `0;` `    ``for` `(``int` `i = 0; i < n; i++) {``        ``count[arr[i]]++;``    ``}` `    ``// remaining_choices denotes the remaining``    ``// elements to select inorder to form quadruple``    ``int` `remaining_choices = 4;``    ``int` `ans = 1;` `    ``// traverse the elements of the map in reverse order``    ``for` `(``auto` `iter = count.rbegin(); iter != count.rend(); ++iter) {``        ``int` `number = iter->first;``        ``int` `frequency = iter->second;` `        ``// If Frequency of element < remaining choices,``        ``// select all of these elements, else select only``        ``// the number of elements required``        ``int` `toSelect = min(remaining_choices, frequency);``        ``ans = ans * NCR(frequency, toSelect);` `        ``// Decrement remaining_choices acc to the number``        ``// of the current elements selected``        ``remaining_choices -= toSelect;` `        ``// if the quadruple is formed stop the algorithm``        ``if` `(!remaining_choices) {``            ``break``;``        ``}``    ``}``    ``return` `ans;``}` `// Driver Code``int` `main()``{``    ``int` `arr[] = { 1, 2, 3, 3, 3, 5 };``    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr);` `    ``int` `maxQuadrupleWays = findWays(arr, n);``    ``cout << maxQuadrupleWays;` `    ``return` `0;``}`

## Java

 `// Java program to find the number of Quadruples``// having maximum product``import` `java.util.*;``class` `Solution``{``// Returns the number of ways to select r objects``// out of available n choices``static` `int` `NCR(``int` `n, ``int` `r)``{``    ``int` `numerator = ``1``;``    ``int` `denominator = ``1``;` `    ``// ncr = (n * (n - 1) * (n - 2) * .....``    ``// ... (n - r + 1)) / (r * (r - 1) * ... * 1)``    ``while` `(r > ``0``) {``        ``numerator *= n;``        ``denominator *= r;``        ``n--;``        ``r--;``    ``}` `    ``return` `(numerator / denominator);``}` `// Returns the number of quadruples having maximum product``static` `int` `findWays(``int` `arr[], ``int` `n)``{``    ``// stores the frequency of each element``    ``HashMap count= ``new` `HashMap();` `    ``if` `(n < ``4``)``        ``return` `0``;` `    ``for` `(``int` `i = ``0``; i < n; i++) {``        ``count.put(arr[i],(count.get(arr[i])==``null``?``0``🙁``int``)count.get(arr[i])));``    ``}` `    ``// remaining_choices denotes the remaining``    ``// elements to select inorder to form quadruple``    ``int` `remaining_choices = ``4``;``    ``int` `ans = ``1``;``    ` `    ``// Getting an iterator``        ``Iterator hmIterator = count.entrySet().iterator();``  ` `        ``while` `(hmIterator.hasNext()) {``            ``Map.Entry mapElement = (Map.Entry)hmIterator.next();``            ``int` `number =(``int``) mapElement.getKey();``            ``int` `frequency =(``int``)mapElement.getValue();``            ` `              ``// If Frequency of element < remaining choices,``        ``// select all of these elements, else select only``        ``// the number of elements required``        ``int` `toSelect = Math.min(remaining_choices, frequency);``        ``ans = ans * NCR(frequency, toSelect);` `        ``// Decrement remaining_choices acc to the number``        ``// of the current elements selected``        ``remaining_choices -= toSelect;` `        ``// if the quadruple is formed stop the algorithm``        ``if` `(remaining_choices==``0``) {``            ``break``;``        ``}``        ``}``   ` `    ``return` `ans;``}` `// Driver Code``public` `static` `void` `main(String args[])``{``    ``int` `arr[] = { ``1``, ``2``, ``3``, ``3``, ``3``, ``5` `};``    ``int` `n = arr.length;` `    ``int` `maxQuadrupleWays = findWays(arr, n);``    ``System.out.print( maxQuadrupleWays);``}``}``//contributed by Arnab Kundu`

## Python3

 `# Python3 program to find``# the number of Quadruples``# having maximum product``from` `collections ``import` `defaultdict` `# Returns the number of ways``# to select r objects out of``# available n choices``def` `NCR(n, r):` `    ``numerator ``=` `1``    ``denominator ``=` `1` `    ``# ncr = (n * (n - 1) *``    ``# (n - 2) * .....``    ``# ... (n - r + 1)) /``    ``# (r * (r - 1) * ... * 1)``    ``while` `(r > ``0``):``        ``numerator ``*``=` `n``        ``denominator ``*``=` `r``        ``n ``-``=` `1``        ``r ``-``=` `1``        ` `    ``return` `(numerator ``/``/` `denominator)` `# Returns the number of``# quadruples having``# maximum product``def` `findWays(arr, n):` `    ``# stores the frequency``    ``# of each element``    ``count ``=` `defaultdict (``int``)` `    ``if` `(n < ``4``):``        ``return` `0` `    ``for` `i ``in` `range` `(n):``        ``count[arr[i]] ``+``=` `1` `    ``# remaining_choices denotes``    ``# the remaining elements to``    ``# select inorder to form quadruple``    ``remaining_choices ``=` `4``    ``ans ``=` `1` `    ``# traverse the elements of``    ``# the map in reverse order``    ``for` `it ``in` `reversed``(``sorted``(count.keys())):``        ``number ``=` `it``        ``frequency ``=` `count[it]` `        ``# If Frequency of element <``        ``# remaining choices, select``        ``# all of these elements,``        ``# else select only the``        ``# number of elements required``        ``toSelect ``=` `min``(remaining_choices,``                       ``frequency)``        ``ans ``=` `ans ``*` `NCR(frequency,``                        ``toSelect)` `        ``# Decrement remaining_choices``        ``# acc to the number of the``        ``# current elements selected``        ``remaining_choices ``-``=` `toSelect` `        ``# if the quadruple is``        ``# formed stop the algorithm``        ``if` `(``not` `remaining_choices):``            ``break``    ``return` `ans` `# Driver Code``if` `__name__ ``=``=` `"__main__"``:``  ` `    ``arr ``=` `[``1``, ``2``, ``3``, ``3``, ``3``, ``5``]``    ``n ``=` `len``(arr)``    ``maxQuadrupleWays ``=` `findWays(arr, n)``    ``print` `(maxQuadrupleWays)` `# This code is contributed by Chitranayal`

## Javascript

 ``

Output:

`1`

Time Complexity: O(NlogN), where N is the size of the array.

Auxiliary Space: O(N)

My Personal Notes arrow_drop_up