Minimum size of subset of pairs whose sum is at least the remaining array elements
Last Updated :
03 Apr, 2023
Given two arrays A[] and B[] both consisting of N positive integers, the task is to find the minimum size of the subsets of pair of elements (A[i], B[i]) such that the sum of all the pairs of subsets is at least the sum of remaining array elements A[] which are not including in the subset i.e., (A[0] + B[0] + A[1] + B[1] + … + A[K – 1] + B[K – 1] >= A[K + 1] + … + A[N – 1].
Examples:
Input: A[] = {3, 2, 2}, B[] = {2, 3, 1}
Output: 1
Explanation:
Choose the subset as {(3, 2)}. Now, the sum of subsets is 3 + 2 = 5, which greater than sum of remaining A[] = 3 + 1 = 4.
Input: A[] = {2, 2, 2, 2, 2}, B[] = {1, 1, 1, 1, 1}
Output: 3
Naive Approach: The simplest approach is to generate all possible subsets of the given pairs of elements and print the size of that subset that satisfies the given criteria and has a minimum size.
Time Complexity: O(2N)
Auxiliary Space: O(1)
Efficient Approach: The given problem can be solved by using the Greedy Approach, the idea is to use sorting and observation can be made that choosing the ith pair as a part of the resultant subset the difference between the 2 subsets decreases by the amount (2*S[i] + U[i]). Follow the steps below to solve the problem:
- Initialize an array, say difference[] of size N that stores the value of (2*A[i] + B[i]) for each pair of elements.
- Initialize a variable, say sum that keeps the track of the sum of remaining array elements A[i].
- Initialize a variable, say K that keeps the track of the size of the resultant subset.
- Iterate over the range [0, N) and update the value of difference[i] as the value of (2*A[i] + B[i]) and decrement the value of sum by the value A[i].
- Sort the given array difference[] in increasing order.
- Traverse the array difference[] in a reverse manner until the sum is negative and add the value of difference[i] to the sum and increment the value of K by 1.
- After completing the above steps, print the value of K as the result.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void maximizeApples(vector< int >& U, vector< int >& S, int N)
{
vector< int > x(N);
int sum = 0;
for ( int i = 0; i < N; i++) {
sum -= S[i];
x[i] += 2 * S[i] + U[i];
}
sort(x.begin(), x.end());
int ans = 0;
int j = N - 1;
while (sum <= 0) {
sum += x[j--];
ans++;
}
cout << ans;
}
int main()
{
vector< int > A = { 1, 1, 1, 1, 1 };
vector< int > B = { 2, 2, 2, 2, 2 };
int N = A.size();
maximizeApples(A, B, N);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
private static void maximizeApples(
int [] U, int [] S, int N)
{
int [] x = new int [N];
int sum = 0 ;
for ( int i = 0 ; i < N; i++) {
sum -= S[i];
x[i] += 2 * S[i] + U[i];
}
Arrays.sort(x);
int ans = 0 ;
int j = N - 1 ;
while (sum <= 0 ) {
sum += x[j--];
ans++;
}
System.out.println(ans);
}
public static void main(String[] args)
{
int [] A = new int [] { 1 , 1 , 1 , 1 , 1 };
int [] B = new int [] { 2 , 2 , 2 , 2 , 2 };
int N = A.length;
maximizeApples(A, B, N);
}
}
|
Python3
def maximizeApples(U, S, N):
x = [ 0 ] * N
sum = 0
for i in range (N):
sum - = S[i]
x[i] + = 2 * S[i] + U[i]
x.sort()
ans = 0
j = N - 1
while sum < = 0 :
sum + = x[j]
j = j - 1
ans = ans + 1
print (ans)
A = [ 1 , 1 , 1 , 1 , 1 ]
B = [ 2 , 2 , 2 , 2 , 2 ]
N = len (A)
maximizeApples(A, B, N)
|
C#
using System.Collections.Generic;
using System;
class GFG
{
static void maximizeApples( int [] U, int [] S, int N)
{
List< int > x = new List< int >();
int sum = 0;
for ( int i = 0; i < N; i++)
{
sum -= S[i];
x.Add( 2 * S[i] + U[i]);
}
x.Sort();
int ans = 0;
int j = N - 1;
while (sum <= 0) {
sum += x[j--];
ans++;
}
Console.WriteLine(ans);
}
public static void Main()
{
int [] A = new int [] { 1, 1, 1, 1, 1 };
int [] B = new int [] { 2, 2, 2, 2, 2 };
int N = A.Length;
maximizeApples(A, B, N);
}
}
|
Javascript
<script>
function maximizeApples(U, S, N) {
let x = new Array(N).fill(0);
let sum = 0;
for (let i = 0; i < N; i++) {
sum -= S[i];
x[i] += 2 * S[i] + U[i];
}
x.sort((a, b) => a - b);
let ans = 0;
let j = N - 1;
while (sum <= 0) {
sum += x[j--];
ans++;
}
document.write(ans);
}
let A = [1, 1, 1, 1, 1];
let B = [2, 2, 2, 2, 2];
let N = A.length;
maximizeApples(A, B, N);
</script>
|
Time Complexity: O(N*log N)
Auxiliary Space: O(N)
Another Approach: To solve this problem is by using binary search. The idea is to binary search for the minimum size of the subset of pairs such that the sum of the pairs is at least the sum of remaining array elements.
The steps for this approach are as follows:
- Calculate the sum of all elements in array A and store it in a variable called totalSum.
- Initialize two pointers, low and high. low is initially set to 0 and high is set to totalSum.
- While low is less than or equal to high, do the following: a. Calculate the mid-point of low and high and store it in a variable called mid. b. Initialize two variables, subsetSum and remainingSum, to 0. c. Iterate through the arrays A and B and for each i-th index, do the following: i. If (A[i] + B[i]) is less than or equal to mid, add it to the subsetSum. ii. Otherwise, add A[i] to the remainingSum. d. If subsetSum is greater than or equal to remainingSum, set high to mid – 1 and store mid in a variable called ans. e. Otherwise, set low to mid + 1.
- Return ans.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int min_subset_size(vector< int >& A, vector< int >& B) {
int totalSum = accumulate(A.begin(), A.end(), 0);
int low = 0, high = totalSum;
int ans = -1;
while (low <= high) {
int mid = (low + high) / 2;
int subsetSum = 0, remainingSum = 0;
for ( int i = 0; i < A.size(); i++) {
if (A[i] + B[i] <= mid) {
subsetSum += A[i] + B[i];
} else {
remainingSum += A[i];
}
}
if (subsetSum >= remainingSum) {
high = mid - 1;
ans = mid;
} else {
low = mid + 1;
}
}
return ans;
}
int main() {
vector< int > A = {2, 2, 2, 2, 2};
vector< int > B = {1, 1, 1, 1, 1};
cout << min_subset_size(A, B) << endl;
return 0;
}
|
Java
import java.util.*;
public class Main {
public static int minSubsetSize(List<Integer> A, List<Integer> B) {
int totalSum = 0 ;
for ( int i = 0 ; i < A.size(); i++) {
totalSum += A.get(i);
}
int low = 0 , high = totalSum;
int ans = - 1 ;
while (low <= high) {
int mid = (low + high) / 2 ;
int subsetSum = 0 , remainingSum = 0 ;
for ( int i = 0 ; i < A.size(); i++) {
if (A.get(i) + B.get(i) <= mid) {
subsetSum += A.get(i) + B.get(i);
} else {
remainingSum += A.get(i);
}
}
if (subsetSum >= remainingSum) {
high = mid - 1 ;
ans = mid;
} else {
low = mid + 1 ;
}
}
return ans;
}
public static void main(String[] args) {
List<Integer> A = new ArrayList<>(Arrays.asList( 2 , 2 , 2 , 2 , 2 ));
List<Integer> B = new ArrayList<>(Arrays.asList( 1 , 1 , 1 , 1 , 1 ));
System.out.println(minSubsetSize(A, B));
}
}
|
Python3
def min_subset_size(A, B):
totalSum = sum (A)
low = 0
high = totalSum
ans = - 1
while low < = high:
mid = (low + high) / / 2
subsetSum = 0
remainingSum = 0
for i in range ( len (A)):
if A[i] + B[i] < = mid:
subsetSum + = A[i] + B[i]
else :
remainingSum + = A[i]
if subsetSum > = remainingSum:
high = mid - 1
ans = mid
else :
low = mid + 1
return ans
A = [ 2 , 2 , 2 , 2 , 2 ]
B = [ 1 , 1 , 1 , 1 , 1 ]
print (min_subset_size(A, B))
|
C#
using System;
using System.Linq;
using System.Collections.Generic;
public class Program {
public static int MinSubsetSize(List< int > A,
List< int > B)
{
int totalSum = A.Sum();
int low = 0, high = totalSum;
int ans = -1;
while (low <= high) {
int mid = (low + high) / 2;
int subsetSum = 0, remainingSum = 0;
for ( int i = 0; i < A.Count; i++) {
if (A[i] + B[i] <= mid) {
subsetSum += A[i] + B[i];
}
else {
remainingSum += A[i];
}
}
if (subsetSum >= remainingSum) {
high = mid - 1;
ans = mid;
}
else {
low = mid + 1;
}
}
return ans;
}
public static void Main()
{
List< int > A = new List< int >{ 2, 2, 2, 2, 2 };
List< int > B = new List< int >{ 1, 1, 1, 1, 1 };
Console.WriteLine(MinSubsetSize(A, B));
}
}
|
Javascript
function min_subset_size(A, B) {
let totalSum = A.reduce((a,b) => a + b);
let low = 0;
let high = totalSum;
let ans = -1;
while (low <= high) {
let mid = Math.floor((low + high) / 2);
let subsetSum = 0;
let remainingSum = 0;
for (let i = 0; i < A.length; i++) {
if (A[i] + B[i] <= mid) {
subsetSum += A[i] + B[i];
} else {
remainingSum += A[i];
}
}
if (subsetSum >= remainingSum) {
high = mid - 1;
ans = mid;
} else {
low = mid + 1;
}
}
return ans;
}
let A = [2, 2, 2, 2, 2];
let B = [1, 1, 1, 1,1];
console.log(min_subset_size(A, B));
|
Time complexity: O(N*log(totalSum))
Auxiliary space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...