给定一组整数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
Javascript
2
时间复杂度: O(N)
辅助空间: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。