Partition a set into two non-empty subsets such that the difference of subset sums is maximum

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:



 
 

abs((totalSum – min(S)) – min(S)) or abs(totalSum – 2×min(S)), where S is the set of integers

 

 
 

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:

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ Program for above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to return the maximum
// difference between the subset sums
int maxDiffSubsets(int arr[], int N)
{
    // Stores the total
    // sum of the array
    int totalSum = 0;
 
    // Checks for positive
    // and negative elements
    bool pos = false, neg = false;
 
    // Stores the minimum element
    // from the given array
    int min = INT_MAX;
 
    // Traverse the array
    for (int i = 0; i < N; i++)
    {
        // Calculate total sum
        totalSum += abs(arr[i]);
 
        // Mark positive element
        // present in the set
        if (arr[i] > 0)
            pos = true;
 
        // Mark negative element
        // present in the set
        if (arr[i] < 0)
            neg = true;
 
        // Find the minimum
        // element of the set
        if (arr[i] < min)
            min = arr[i];
    }
 
    // If the array contains both
    // positive and negative elements
    if (pos && neg)
        return totalSum;
 
    // Otherwise
    else
        return totalSum - 2 * min;
}
 
// Driver Code
int main()
{
    // Given the array
    int S[] = {1, 2, 1};
 
    // Length of the array
    int N = sizeof(S) / sizeof(S[0]);
 
    if (N < 2)
        cout << ("Not Possible");
 
    else
        // Function Call
        cout << (maxDiffSubsets(S, N));
}
 
// This code is contributed by Chitranayal
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java Program for above approach
 
import java.util.*;
import java.lang.*;
 
class GFG {
 
    // Function to return the maximum
    // difference between the subset sums
    static int maxDiffSubsets(int[] arr)
    {
        // Stores the total
        // sum of the array
        int totalSum = 0;
 
        // Checks for positive
        // and negative elements
        boolean pos = false, neg = false;
 
        // Stores the minimum element
        // from the given array
        int min = Integer.MAX_VALUE;
 
        // Traverse the array
        for (int i = 0; i < arr.length; i++) {
 
            // Calculate total sum
            totalSum += Math.abs(arr[i]);
 
            // Mark positive element
            // present in the set
            if (arr[i] > 0)
                pos = true;
 
            // Mark negative element
            // present in the set
            if (arr[i] < 0)
                neg = true;
 
            // Find the minimum
            // element of the set
            if (arr[i] < min)
                min = arr[i];
        }
 
        // If the array contains both
        // positive and negative elements
        if (pos && neg)
            return totalSum;
 
        // Otherwise
        else
            return totalSum - 2 * min;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        // Given the array
        int[] S = { 1, 2, 1 };
 
        // Length of the array
        int N = S.length;
 
        if (N < 2)
            System.out.println("Not Possible");
 
        else
            // Function Call
            System.out.println(maxDiffSubsets(S));
    }
}
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program for above approach
import sys
 
# Function to return the maximum
# difference between the subset sums
def maxDiffSubsets(arr):
     
    # Stores the total
    # sum of the array
    totalSum = 0
 
    # Checks for positive
    # and negative elements
    pos = False
    neg = False
 
    # Stores the minimum element
    # from the given array
    min = sys.maxsize
 
    # Traverse the array
    for i in range(len(arr)):
 
        # Calculate total sum
        totalSum += abs(arr[i])
 
        # Mark positive element
        # present in the set
        if (arr[i] > 0):
            pos = True
 
        # Mark negative element
        # present in the set
        if (arr[i] < 0):
            neg = True
 
        # Find the minimum
        # element of the set
        if (arr[i] < min):
            min = arr[i]
 
    # If the array contains both
    # positive and negative elements
    if (pos and neg):
        return totalSum
 
    # Otherwise
    else:
        return totalSum - 2 * min
 
# Driver Code
if __name__ == '__main__':
     
    # Given the array
    S = [ 1, 2, 1 ]
 
    # Length of the array
    N = len(S)
 
    if (N < 2):
        print("Not Possible")
    else:
         
        # Function Call
        print(maxDiffSubsets(S))
         
# This code is contributed by mohit kumar 29
chevron_right

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# Program for above approach
using System;
class GFG{
 
    // Function to return the maximum
    // difference between the subset sums
    static int maxDiffSubsets(int[] arr)
    {
        // Stores the total
        // sum of the array
        int totalSum = 0;
 
        // Checks for positive
        // and negative elements
        bool pos = false, neg = false;
 
        // Stores the minimum element
        // from the given array
        int min = int.MaxValue;
 
        // Traverse the array
        for (int i = 0; i < arr.Length; i++)
        {
            // Calculate total sum
            totalSum += Math.Abs(arr[i]);
 
            // Mark positive element
            // present in the set
            if (arr[i] > 0)
                pos = true;
 
            // Mark negative element
            // present in the set
            if (arr[i] < 0)
                neg = true;
 
            // Find the minimum
            // element of the set
            if (arr[i] < min)
                min = arr[i];
        }
 
        // If the array contains both
        // positive and negative elements
        if (pos && neg)
            return totalSum;
 
        // Otherwise
        else
            return totalSum - 2 * min;
    }
 
    // Driver Code
    public static void Main(String[] args)
    {
        // Given the array
        int[] S = {1, 2, 1};
 
        // Length of the array
        int N = S.Length;
 
        if (N < 2)
            Console.WriteLine("Not Possible");
        else
           
            // Function Call
            Console.WriteLine(maxDiffSubsets(S));
    }
}
 
// This code is contributed by Rajput-Ji
chevron_right

Output: 
2






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

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




Recommended Posts:


Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Article Tags :