Partition a set into two non-empty subsets such that the difference of subset sums is maximum
Last Updated :
21 Apr, 2021
Given a set of integers S, the task is to divide the given set into two non-empty sets S1 and S2 such that the absolute difference between their sums is maximum, i.e., abs(sum(S1) – sum(S2)) is maximum.
Example:
Input: S[] = { 1, 2, 1 }
Output: 2
Explanation:
The subsets are {1} and {2, 1}. Their absolute difference is
abs(1 – (2+1)) = 2, which is maximum.
Input: S[] = { -2, 3, -1, 5 }
Output: 11
Explanation:
The subsets are {-1, -2} and {3, 5}. Their absolute difference is
abs((-1, -2) – (3+5)) = 11, which is maximum.
Naive Approach: Generate and store all the subsets of the set of integers and find the maximum absolute difference between the sum of the subset and the difference between the total sum of the set and the sum of that subset, i.e, abs(sum(S1) – (totalSum – sum(S1)).
Time Complexity: O(2N)
Auxiliary Space: O(2N)
Efficient Approach: To optimize the naive approach, the idea is to use some mathematical observations. The problem can be divided into two cases:
- If the set contains only positive integers or only negative integers, then the maximum difference is obtained by splitting the set such that one subset contains only the minimum element of the set and the other subset contains all the remaining elements of the set, i.e.,
abs((totalSum – min(S)) – min(S)) or abs(totalSum – 2×min(S)), where S is the set of integers
- If the set contains both positive and negative integers, then the maximum difference is obtained by splitting the set such that one subset contains all the positive integers and the other subset contains all the negative integers, i.e.,
abs(sum(S1) – sum(S2)) or abs(sum(S)), where S1, S2 is the set of positive and negative integers respectively.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int maxDiffSubsets( int arr[], int N)
{
int totalSum = 0;
bool pos = false , neg = false ;
int min = INT_MAX;
for ( int i = 0; i < N; i++)
{
totalSum += abs (arr[i]);
if (arr[i] > 0)
pos = true ;
if (arr[i] < 0)
neg = true ;
if (arr[i] < min)
min = arr[i];
}
if (pos && neg)
return totalSum;
else
return totalSum - 2 * min;
}
int main()
{
int S[] = {1, 2, 1};
int N = sizeof (S) / sizeof (S[0]);
if (N < 2)
cout << ( "Not Possible" );
else
cout << (maxDiffSubsets(S, N));
}
|
Java
import java.util.*;
import java.lang.*;
class GFG {
static int maxDiffSubsets( int [] arr)
{
int totalSum = 0 ;
boolean pos = false , neg = false ;
int min = Integer.MAX_VALUE;
for ( int i = 0 ; i < arr.length; i++) {
totalSum += Math.abs(arr[i]);
if (arr[i] > 0 )
pos = true ;
if (arr[i] < 0 )
neg = true ;
if (arr[i] < min)
min = arr[i];
}
if (pos && neg)
return totalSum;
else
return totalSum - 2 * min;
}
public static void main(String[] args)
{
int [] S = { 1 , 2 , 1 };
int N = S.length;
if (N < 2 )
System.out.println( "Not Possible" );
else
System.out.println(maxDiffSubsets(S));
}
}
|
Python3
import sys
def maxDiffSubsets(arr):
totalSum = 0
pos = False
neg = False
min = sys.maxsize
for i in range ( len (arr)):
totalSum + = abs (arr[i])
if (arr[i] > 0 ):
pos = True
if (arr[i] < 0 ):
neg = True
if (arr[i] < min ):
min = arr[i]
if (pos and neg):
return totalSum
else :
return totalSum - 2 * min
if __name__ = = '__main__' :
S = [ 1 , 2 , 1 ]
N = len (S)
if (N < 2 ):
print ( "Not Possible" )
else :
print (maxDiffSubsets(S))
|
C#
using System;
class GFG{
static int maxDiffSubsets( int [] arr)
{
int totalSum = 0;
bool pos = false , neg = false ;
int min = int .MaxValue;
for ( int i = 0; i < arr.Length; i++)
{
totalSum += Math.Abs(arr[i]);
if (arr[i] > 0)
pos = true ;
if (arr[i] < 0)
neg = true ;
if (arr[i] < min)
min = arr[i];
}
if (pos && neg)
return totalSum;
else
return totalSum - 2 * min;
}
public static void Main(String[] args)
{
int [] S = {1, 2, 1};
int N = S.Length;
if (N < 2)
Console.WriteLine( "Not Possible" );
else
Console.WriteLine(maxDiffSubsets(S));
}
}
|
Javascript
<script>
function maxDiffSubsets(arr) {
var totalSum = 0;
var pos = false , neg = false ;
var min = Number.MAX_VALUE;
for (i = 0; i < arr.length; i++) {
totalSum += Math.abs(arr[i]);
if (arr[i] > 0)
pos = true ;
if (arr[i] < 0)
neg = true ;
if (arr[i] < min)
min = arr[i];
}
if (pos && neg)
return totalSum;
else
return totalSum - 2 * min;
}
var S = [ 1, 2, 1 ];
var N = S.length;
if (N < 2)
document.write( "Not Possible" );
else
document.write(maxDiffSubsets(S));
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...