给定一组整数S ,任务是将给定集合分为两个非空集合S1和S2 ,以使它们的和之间的绝对差最大,即abs(sum(S1)– sum(S2))为最大。
例子:
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.
天真的方法:生成并存储整数集的所有子集,并找到该子集的和与该集合的总和与该子集的和之间的差之间的最大绝对差,即abs(sum(S1 )–(totalSum – sum(S1)) 。
时间复杂度: O(2 N )
辅助空间: O(2 N )
高效的方法:为了优化幼稚的方法,其想法是使用一些数学观察结果。该问题可以分为两种情况:
- 如果集合仅包含正整数或仅包含负整数,则可通过拆分集合以使一个子集仅包含集合的最小元素,而另一个子集包含集合的所有其余元素,从而获得最大差异。
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.
下面是上述方法的实现:
C++
// C++ Program for above approach
#include
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
Java
// 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));
}
}
Python3
# 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
C#
// 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
2
时间复杂度: O(N)
辅助空间: O(1)