Given an array arr[ ] consisting of N integers, the task is to find maximum difference between the sum of two subsets obtained by partitioning the array into any two non-empty subsets.
Note: The subsets cannot any common element. A subset can contain repeating elements.
Examples:
Input: arr[] = {1, 3, 2, 4, 5}
Output: 13
Explanation: The partitions {3, 2, 4, 5} and {1} maximizes the difference between the subsets.
Input: arr[] = {1, -5, 3, 2, -7}
Output: 18
Explanation: The partitions {1, 3, 2} and {-5, -7} maximizes the difference between the subsets.
Approach: This problem can be solved using greedy approach. In this problem both the subsets A and B must be non-empty. So we have to put at least one element in both of them. We try to make sum of elements in subset A as greater as possible and sum of elements in subset B as smaller as possible. Finally we print sum(A) – sum(B).
Follow the steps given below to solve the problem:
- When arr[ ] contains both non-negative and negative numbers, put all non-negative numbers in subset A and negative numbers in subset B, and print sum(A) – sum(B).
- When all numbers are positive, put all numbers in subset A except the smallest positive number put that in subset B, and print sum(A) – sum(B).
- When all numbers are negative, put all numbers in subset B except the largest negative put that in subset A, and print sum(A) – sum(B).
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int maxSumAfterPartition( int arr[], int n)
{
vector< int > pos;
vector< int > neg;
int zero = 0;
int pos_sum = 0;
int neg_sum = 0;
for ( int i = 0; i < n; i++) {
if (arr[i] > 0) {
pos.push_back(arr[i]);
pos_sum += arr[i];
}
else if (arr[i] < 0) {
neg.push_back(arr[i]);
neg_sum += arr[i];
}
else {
zero++;
}
}
int ans = 0;
sort(pos.begin(), pos.end());
sort(neg.begin(), neg.end(), greater< int >());
if (pos.size() > 0 && neg.size() > 0) {
ans = (pos_sum - neg_sum);
}
else if (pos.size() > 0) {
if (zero > 0) {
ans = (pos_sum);
}
else {
ans = (pos_sum - 2 * pos[0]);
}
}
else {
if (zero > 0) {
ans = (-1 * neg_sum);
}
else {
ans = (neg[0] - (neg_sum - neg[0]));
}
}
return ans;
}
int main()
{
int arr[] = { 1, 2, 3, -5, -7 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << maxSumAfterPartition(arr, n);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static int maxSumAfterPartition( int arr[], int n)
{
ArrayList<Integer> pos
= new ArrayList<Integer>();
ArrayList<Integer> neg
= new ArrayList<Integer>();
int zero = 0 ;
int pos_sum = 0 ;
int neg_sum = 0 ;
for ( int i = 0 ; i < n; i++) {
if (arr[i] > 0 ) {
pos.add(arr[i]);
pos_sum += arr[i];
}
else if (arr[i] < 0 ) {
neg.add(arr[i]);
neg_sum += arr[i];
}
else {
zero++;
}
}
int ans = 0 ;
Collections.sort(pos);
Collections.sort(neg);
if (pos.size() > 0 && neg.size() > 0 ) {
ans = (pos_sum - neg_sum);
}
else if (pos.size() > 0 ) {
if (zero > 0 ) {
ans = (pos_sum);
}
else {
ans = (pos_sum - 2 * pos.get( 0 ));
}
}
else {
if (zero > 0 ) {
ans = (- 1 * neg_sum);
}
else {
ans = (neg.get( 0 ) - (neg_sum - neg.get( 0 )));
}
}
return ans;
}
public static void main(String[] args)
{
int arr[] = { 1 , 2 , 3 , - 5 , - 7 };
int n = 5 ;
System.out.println(maxSumAfterPartition(arr, n));
}
}
|
Python3
def maxSumAfterPartition(arr, n):
pos = []
neg = []
zero = 0
pos_sum = 0
neg_sum = 0
for i in range (n):
if (arr[i] > 0 ):
pos.append(arr[i])
pos_sum + = arr[i]
elif (arr[i] < 0 ):
neg.append(arr[i])
neg_sum + = arr[i]
else :
zero + = 1
ans = 0
pos.sort()
neg.sort(reverse = True )
if ( len (pos) > 0 and len (neg) > 0 ):
ans = (pos_sum - neg_sum)
elif ( len (pos) > 0 ):
if (zero > 0 ):
ans = (pos_sum)
else :
ans = (pos_sum - 2 * pos[ 0 ])
else :
if (zero > 0 ):
ans = ( - 1 * neg_sum)
else :
ans = (neg[ 0 ] - (neg_sum - neg[ 0 ]))
return ans
if __name__ = = '__main__' :
arr = [ 1 , 2 , 3 , - 5 , - 7 ]
n = len (arr)
print (maxSumAfterPartition(arr, n))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int maxSumAfterPartition( int []arr, int n)
{
List< int > pos = new List< int >();
List< int > neg = new List< int >();
int zero = 0;
int pos_sum = 0;
int neg_sum = 0;
for ( int i = 0; i < n; i++) {
if (arr[i] > 0) {
pos.Add(arr[i]);
pos_sum += arr[i];
}
else if (arr[i] < 0) {
neg.Add(arr[i]);
neg_sum += arr[i];
}
else {
zero++;
}
}
int ans = 0;
pos.Sort();
neg.Sort();
neg.Reverse();
if (pos.Count > 0 && neg.Count > 0) {
ans = (pos_sum - neg_sum);
}
else if (pos.Count > 0) {
if (zero > 0) {
ans = (pos_sum);
}
else {
ans = (pos_sum - 2 * pos[0]);
}
}
else {
if (zero > 0) {
ans = (-1 * neg_sum);
}
else {
ans = (neg[0] - (neg_sum - neg[0]));
}
}
return ans;
}
public static void Main()
{
int []arr = { 1, 2, 3, -5, -7 };
int n = arr.Length;
Console.Write(maxSumAfterPartition(arr, n));
}
}
|
Javascript
<script>
function maxSumAfterPartition(arr, n) {
let pos = [];
let neg = [];
let zero = 0;
let pos_sum = 0;
let neg_sum = 0;
for (let i = 0; i < n; i++) {
if (arr[i] > 0) {
pos.push(arr[i]);
pos_sum += arr[i];
}
else if (arr[i] < 0) {
neg.push(arr[i]);
neg_sum += arr[i];
}
else {
zero++;
}
}
let ans = 0;
pos.sort( function (a, b) { return a - b })
neg.sort( function (a, b) { return b - a })
if (pos.length > 0 && neg.length > 0) {
ans = (pos_sum - neg_sum);
}
else if (pos.length > 0) {
if (zero > 0) {
ans = (pos_sum);
}
else {
ans = (pos_sum - 2 * pos[0]);
}
}
else {
if (zero > 0) {
ans = (-1 * neg_sum);
}
else {
ans = (neg[0] - (neg_sum - neg[0]));
}
}
return ans;
}
let arr = [1, 2, 3, -5, -7];
let n = arr.length;
document.write(maxSumAfterPartition(arr, n));
</script>
|
Time Complexity: O(NlogN)
Auxiliary Space: O(N)