Given an array arr[] of even size consisting of positive integers, partition its elements into pairs such that every element belongs to exactly one pair. Find the minimum possible sum of the products of all pairs
Examples:
Input: arr[] = [9, 2, 8, 4, 5, 7, 6, 0]
Output: 74
Explanation: Required sum can be obtained as 9 * 0 + 8 * 2 + 7 * 4 + 6 * 5 which is equal to 74.
Input: arr[] = [1, 2, 3, 4]
Output: 10
Explanation: array is already sorted 1 * 4 + 2 * 3 = 10.
Table of Content
[Naive Approach] Try Every Permutation - O(n × n!) Time and O(1) Space
The idea is to generate all possible permutations of the array. For each permutation, form pairs using consecutive elements, compute the sum of their products, and keep track of the minimum sum. Since every arrangement is considered, the minimum sum obtained is the answer.
#include <algorithm>
#include <climits>
#include <iostream>
#include <vector>
using namespace std;
int altProduct(vector<int> &arr)
{
int n = arr.size();
// Sorting the array to generate all permutations
sort(arr.begin(), arr.end());
// Initializing the result
int res = INT_MAX;
// Generating all possible permutations
do
{
int sum = 0;
// Forming pairs using consecutive elements
for (int i = 0; i < n; i += 2)
sum += arr[i] * arr[i + 1];
// Updating the minimum sum
res = min(res, sum);
} while (next_permutation(arr.begin(), arr.end()));
return res;
}
int main()
{
vector<int> arr = {9, 2, 8, 4, 5, 7, 6, 0};
cout << altProduct(arr);
return 0;
}
import java.util.Arrays;
import java.util.Comparator;
public class GFG {
public static int altProduct(int[] arr)
{
Arrays.sort(arr);
int res = Integer.MAX_VALUE;
do {
int sum = 0;
for (int i = 0; i < arr.length; i += 2)
sum += arr[i] * arr[i + 1];
res = Math.min(res, sum);
} while (nextPermutation(arr));
return res;
}
public static boolean nextPermutation(int[] arr)
{
for (int a = arr.length - 2; a >= 0; --a) {
if (arr[a] < arr[a + 1]) {
for (int b = arr.length - 1;; --b) {
if (arr[b] > arr[a]) {
int t = arr[a];
arr[a] = arr[b];
arr[b] = t;
Arrays.sort(arr, a + 1, arr.length);
return true;
}
}
}
}
Arrays.sort(arr);
return false;
}
public static void main(String[] args)
{
int[] arr = { 9, 2, 8, 4, 5, 7, 6, 0 };
System.out.println(altProduct(arr));
}
}
from itertools import permutations
def altProduct(arr):
arr.sort()
res = float('inf')
for p in permutations(arr):
sum = 0
for i in range(0, len(arr), 2):
sum += p[i] * p[i + 1]
res = min(res, sum)
return res
if __name__ == '__main__':
arr = [9, 2, 8, 4, 5, 7, 6, 0]
print(altProduct(arr))
using System;
using System.Collections.Generic;
class GFG {
// Function to find the minimum sum of products
static int altProduct(List<int> arr)
{
// Sorting the array to generate all permutations
arr.Sort();
// Initializing the result
int res = int.MaxValue;
// Generating all possible permutations
do {
int sum = 0;
// Forming pairs using consecutive elements
for (int i = 0; i < arr.Count; i += 2)
sum += arr[i] * arr[i + 1];
// Updating the minimum sum
res = Math.Min(res, sum);
} while (NextPermutation(arr));
// Returning the result
return res;
}
static bool NextPermutation(List<int> arr)
{
for (int i = arr.Count - 2; i >= 0; i--) {
if (arr[i] < arr[i + 1]) {
for (int j = arr.Count - 1;; j--) {
if (arr[j] > arr[i]) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
arr.Sort(i + 1, arr.Count - i - 1,
null);
return true;
}
}
}
}
arr.Sort();
return false;
}
static void Main()
{
List<int> arr
= new List<int>{ 9, 2, 8, 4, 5, 7, 6, 0 };
Console.WriteLine(altProduct(arr));
}
}
// Function to find the minimum sum of products
function altProduct(arr)
{
// Sorting the array to generate all permutations
arr.sort((a, b) => a - b);
// Initializing the result
let res = Number.MAX_SAFE_INTEGER;
// Generating all possible permutations
do {
let sum = 0;
// Forming pairs using consecutive elements
for (let i = 0; i < arr.length; i += 2)
sum += arr[i] * arr[i + 1];
// Updating the minimum sum
res = Math.min(res, sum);
} while (nextPermutation(arr));
// Returning the result
return res;
}
function nextPermutation(arr)
{
let i = arr.length - 2;
while (i >= 0 && arr[i] >= arr[i + 1])
i--;
if (i < 0) {
arr.sort((a, b) => a - b);
return false;
}
let j = arr.length - 1;
while (arr[j] <= arr[i])
j--;
[arr[i], arr[j]] = [ arr[j], arr[i] ];
let left = i + 1, right = arr.length - 1;
while (left < right) {
[arr[left], arr[right]] = [ arr[right], arr[left] ];
left++;
right--;
}
return true;
}
// Driver code
let arr = [ 9, 2, 8, 4, 5, 7, 6, 0 ];
console.log(altProduct(arr));
Output
74
[Expected Approach] Greedy Pairing After Sorting - O(n log n) Time and O(1) Space
The idea is to sort the array and directly pair the i-th element from the beginning with the i-th element from the end. This Greedy Approach ensures that the largest element is multiplied with the smallest one to get the minimum sum.
Let us understand with example:
Input: arr[] = [9, 2, 8, 4, 5, 7, 6, 0]
- After sorting, it becomes {0, 2, 4, 5, 6, 7, 8, 9}.
- For i = 0, pair (0, 9), product = 0 × 9 = 0, so sum = 0.
- For i = 1, pair (2, 8), product = 2 × 8 = 16, so sum = 16.
- For i = 2, pair (4, 7), product = 4 × 7 = 28, so sum = 44.
- For i = 3, pair (5, 6), product = 5 × 6 = 30, so sum = 74. Therefore, the output is 74.
#include <iostream>
using namespace std;
int altProduct(vector<int> &arr)
{
int n = arr.size();
// Sorting the array in ascending order
sort(arr.begin(), arr.end());
// Initializing the sum variable
int sum = 0;
// Calculating the sum of alternate products
for (int i = 0; i < n / 2; i++)
sum += (arr[i] * arr[n - i - 1]);
// Returning the final sum
return sum;
}
// Driver code
int main()
{
vector<int> arr = {9, 2, 8, 4, 5, 7, 6, 0};
cout << altProduct(arr);
return 0;
}
import java.util.Arrays;
public class GFG {
public static int altProduct(int[] arr)
{
int n = arr.length;
// Sorting the array in ascending order
Arrays.sort(arr);
// Initializing the sum variable
int sum = 0;
// Calculating the sum of alternate products
for (int i = 0; i < n / 2; i++)
sum += (arr[i] * arr[n - i - 1]);
// Returning the final sum
return sum;
}
// Driver code
public static void main(String[] args)
{
int[] arr = { 9, 2, 8, 4, 5, 7, 6, 0 };
System.out.println(altProduct(arr));
}
}
def altProduct(arr):
n = len(arr)
# Sorting the array in ascending order
arr.sort()
# Initializing the sum variable
sum = 0
# Calculating the sum of alternate products
for i in range(n // 2):
sum += (arr[i] * arr[n - i - 1])
# Returning the final sum
return sum
# Driver code
if __name__ == "__main__":
arr = [9, 2, 8, 4, 5, 7, 6, 0]
print(altProduct(arr))
using System;
using System.Collections.Generic;
class GFG {
static int altProduct(List<int> arr)
{
int n = arr.Count;
// Sorting the array in ascending order
arr.Sort();
// Initializing the sum variable
int sum = 0;
// Calculating the sum of alternate products
for (int i = 0; i < n / 2; i++)
sum += (arr[i] * arr[n - i - 1]);
// Returning the final sum
return sum;
}
// Driver code
static void Main()
{
List<int> arr
= new List<int>{ 9, 2, 8, 4, 5, 7, 6, 0 };
Console.WriteLine(altProduct(arr));
}
}
function altProduct(arr) {
let n = arr.length;
// Sorting the array in ascending order
arr.sort((a, b) => a - b);
// Initializing the sum variable
let sum = 0;
// Calculating the sum of alternate products
for (let i = 0; i < Math.floor(n / 2); i++) {
sum += (arr[i] * arr[n - i - 1]);
}
// Returning the final sum
return sum;
}
// Driver code
let arr = [9, 2, 8, 4, 5, 7, 6, 0];
console.log(altProduct(arr));
Output
74