# Sum of first M fractions formed from Array of primes

• Last Updated : 22 Jun, 2022

Given an integer M and a sorted integer array arr[] of length N containing 1 and N-1 prime numbers, each appearing just once, the task is to find the sum of M smallest possible fractions formed from the given array elements where each fraction is of the form arr[i]/arr[j] (i < j).

Note: Return the answer rounded off to 6 digits after the decimal.

Examples:

Input: arr[] = {1, 2, 3, 5}, M = 2
Output: 0.533333
Explanation: All possible fractions are – {1/2, 1/3, 1/5, 2/3, 2/5, 3/5}
After sorting all possible fractions are {1/5, 1/3, 2/5, 1/2, 3/5, 2/3}
so sum of first M(here 2) will be 1/5+1/3 = 8/15 = 0.533333

Input: arr[] = {7, 9, 11}, M = 1
Output: 0.636364
Explanation: All possible fractions are – {7/9, 7/11, 9/11}
after sorting all possible fractions are  {7/11, 7/9, 9/11}
so sum of first M(here 1) will be 7/11 = 0.636364

Naive Approach: A basic idea is to find all possible fractions formed by the elements in the array and sort them. Then return the sum of first M smallest elements.

Time Complexity: O(N2)
Auxiliary Space: O(N)

Efficient Approach: An efficient approach to solve this problem will be to use the min heap. Following is the idea behind that:

The minimum possible fraction associated with each element will be the one with the highest denominator. So that will be of the form arr[i]/arr[N-1]. Any fraction associated with any array value (arr[i]) will be greater than this.
Based of this we can solve the problem with the help of min heap as shown here:

• Initially put all fractions having value arr[i]/arr[N-1] into the heap, then pop the minimum value and find the next greater fraction associated with its numerator (If the value was arr[i]/arr[j] the next greater fraction associated with arr[i] will be arr[i]/arr[j-1]).
• Put this fraction into the min heap.
• Then again find the minimum from the elements in the heap and repeat the same till M elements are not selected.

Follow the illustration below for a better understanding.

Illustration:

Consider: arr[] = {1, 2, 3, 5}, M = 2

Initially put all the minimum possible fractions associated with each array element.
Heap element of the form {fraction value, numerator index, denominator index}:
-> heap = { {0.2, 0, 3}, {0.4, 1, 3}, {0.6, 2, 3} }

1st Iteration:
-> Minimum value 0.2.
-> Sum = 0 + 0.2 = 0.2.
-> Pop the minimum value. heap { {0.4, 1, 3}, {0.6, 2, 3} }.
-> Next greater fraction associated with 1 is 1/3 = 0.333333.
-> heap = { {0.333333, 0, 2},  {0.4, 1, 3}, {0.6, 2, 3} }.
-> M = 2-1 = 1.

2nd Iteration:
-> Minimum value 0.333333.
-> Sum = 0.2 + 0.333333 = 0.533333.
-> Pop the minimum value. heap = { {0.4, 1, 3}, {0.6, 2, 3} }.
-> Next greater fraction associated with 1 is 1/2 = 0.5.
-> heap = { {0.4, 1, 3}, {0.5, 0, 1}, {0.6, 2, 3} }.
-> M = 1-1 = 0.

So the sum is 0.533333

Follow the steps mentioned below to implement the idea:

• Create a min heap to store the value of fractions and indices of the numerator and the denominator.
• Initially add the minimum possible fractions to the min heap.
• Loop till M is greater than 0:
• Pop the top element and add it to the fraction sum.
• Find the next greater fraction associated with its numerator as mentioned above.
• Push that fraction into the min heap.
• Decrement M by 1.
• Return the sum value as the answer.

Below is the implementation of the above approach:

## C++

 `// C++ program to implement above approach`   `#include ` `using` `namespace` `std;`   `// Structure for storing fractions and index` `struct` `fractionElement {`   `    ``// For storing fractional value` `    ``double` `value;` `    ``int` `i, j;` `    ``fractionElement(``double` `d, ``int` `x, ``int` `y)` `        ``: value(d), i(x), j(y)` `    ``{` `    ``}` `    ``bool` `operator<(``const` `fractionElement& f) ``const` `    ``{` `        ``return` `value > f.value;` `    ``}` `};`   `// Function for getting sum of` `// M smallest fraction` `double` `SumofMfractions(vector<``int``>& A, ``int` `M)` `{` `    ``// Creating a priority_queue based upon` `    ``// our structure` `    ``priority_queue pq;`   `    ``for` `(``int` `i = 0; i < A.size(); i++) {`   `        ``// Pushing element in priority_queue` `        ``// keeping the last index as same` `        ``pq.push(fractionElement((``double``)(A[i])` `                                    ``/ A.back(),` `                                ``i, A.size() - 1));` `    ``}` `    ``double` `sum = 0;`   `    ``while` `(M > 1) {` `        ``auto` `top = pq.top();`   `        ``// Pop up the top element` `        ``pq.pop();`   `        ``// Adding the value to the sum` `        ``sum += top.value;` `        ``top.j--;`   `        ``// Decreasing the last index to get` `        ``// other value pair of i, j` `        ``pq.push(fractionElement(` `            ``(``double``)(A[top.i]) / A[top.j],` `            ``top.i, top.j));`   `        ``M--;` `    ``}`   `    ``// Adding latest top value` `    ``sum += pq.top().value;`   `    ``// returning the sum of m smallest fractions` `    ``return` `sum;` `}`   `// Driver code` `int` `main()` `{` `    ``vector<``int``> A = { 1, 2, 3, 5 };` `    ``int` `M = 2;`   `    ``// Function call` `    ``cout << SumofMfractions(A, M) << endl;` `    ``return` `0;` `}`

## Java

 `// Java code to implement the approach` `import` `java.io.*;` `import` `java.util.*;`   `class` `GFG {` `    ``// Structure for storing fractions and index` `    ``static` `class` `fractionElement` `        ``implements` `Comparable {` `        ``// For storing fractional value` `        ``double` `value;` `        ``int` `i, j;` `        ``fractionElement(``double` `d, ``int` `x, ``int` `y)` `        ``{` `            ``value = d;` `            ``i = x;` `            ``j = y;` `        ``}` `        ``public` `int` `compareTo(fractionElement o)` `        ``{` `            ``if` `(value > o.value)` `                ``return` `1``;` `            ``else` `if` `(value < o.value)` `                ``return` `-``1``;` `            ``return` `0``;` `        ``}` `    ``}`   `    ``// Function for getting sum of` `    ``// M smallest fraction` `    ``static` `double` `SumofMfractions(``int``[] A, ``int` `M)` `    ``{` `        ``// Creating a priority_queue based upon` `        ``// our structure` `        ``PriorityQueue pq` `            ``= ``new` `PriorityQueue<>();`   `        ``for` `(``int` `i = ``0``; i < A.length; i++) {`   `            ``// Pushing element in priority_queue` `            ``// keeping the last index as same` `            ``pq.add(``new` `fractionElement(` `                ``(``double``)(A[i]) / A[A.length - ``1``], i,` `                ``A.length - ``1``));` `        ``}` `        ``double` `sum = ``0``;`   `        ``while` `(M > ``1``) {` `            ``fractionElement top = pq.peek();`   `            ``// Pop up the top element` `            ``pq.remove();`   `            ``// Adding the value to the sum` `            ``sum += top.value;` `            ``top.j--;`   `            ``// Decreasing the last index to get` `            ``// other value pair of i, j` `            ``pq.add(``new` `fractionElement((``double``)(A[top.i])` `                                           ``/ A[top.j],` `                                       ``top.i, top.j));`   `            ``M--;` `        ``}`   `        ``// Adding latest top value` `        ``sum += pq.peek().value;`   `        ``// returning the sum of m smallest fractions` `        ``return` `sum;` `    ``}`   `    ``// Driver code` `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``int``[] A = { ``1``, ``2``, ``3``, ``5` `};` `        ``int` `M = ``2``;` `        ``// Function call` `        ``System.out.println(SumofMfractions(A, M));` `    ``}` `}` `// This code is contributed by Karandeep1234`

Output

`0.533333`

Time Complexity: O(M * logN)
Auxiliary Space: O(N)

My Personal Notes arrow_drop_up
Related Articles