📌  相关文章
📜  将集合划分为两个非空子集,以使子集和的差最大

📅  最后修改于: 2021-04-26 09:39:35             🧑  作者: Mango

给定一组整数S ,任务是将给定集合分为两个非空集合S1S2 ,以使它们的和之间的绝对差最大,即abs(sum(S1)– sum(S2))为最大。

例子:

天真的方法:生成并存储整数集的所有子集,并找到该子集的和与该集合的总和与该子集的和之间的差之间的最大绝对差,即abs(sum(S1 )–(totalSum – sum(S1))
时间复杂度: O(2 N )
辅助空间: O(2 N )

高效的方法:为了优化幼稚的方法,其想法是使用一些数学观察结果。该问题可以分为两种情况:

  • 如果集合仅包含正整数或仅包含负整数,则可通过拆分集合以使一个子集仅包含集合的最小元素,而另一个子集包含集合的所有其余元素,从而获得最大差异。
  • 如果该集合同时包含正整数和负整数,则可以通过拆分集合来获得最大差异,以使一个子集包含所有正整数,而另一个子集包含所有负整数,即

下面是上述方法的实现:

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)