📌  相关文章
📜  数组的两个子集之和的最大可能差 | 2套

📅  最后修改于: 2021-10-26 05:13:07             🧑  作者: Mango

给定一个由N 个整数组成的数组 arr[] ,任务是找到通过将数组划分为任意两个非空子集而获得的两个子集之和的最大差值。
注意:子集不能有任何公共元素。子集可以包含重复元素。

例子:

方法:这个问题可以使用贪心方法来解决。在这个问题中,子集 A 和 B 都必须是非空的。所以我们必须在它们两个中至少放入一个元素。我们尽量使子集 A 中元素的总和尽可能大,而子集 B 中元素的总和尽可能小。最后我们打印 sum(A) – sum(B)。

请按照以下步骤解决问题:

  • arr[ ] 同时包含非负数和负数时,将所有非负数放在子集 A 中,将负数放在子集 B 中,并打印sum(A) – sum(B)
  • 当所有数字都是正数时,将所有数字放入子集 A 中,除了最小的正数放入子集 B 中,并打印sum(A) – sum(B)
  • 当所有数均为负数时,将除最大负数外的所有数放入子集A中,并打印sum(A) – sum(B)。

下面是上述方法的实现:

C++
// C++ Program for the above approach
 
#include 
using namespace std;
 
int maxSumAfterPartition(int arr[], int n)
{
    // Stores the positive elements
    vector pos;
 
    // Stores the negative elements
    vector neg;
 
    // Stores the count of 0s
    int zero = 0;
 
    // Sum of all positive numbers
    int pos_sum = 0;
 
    // Sum of all negative numbers
    int neg_sum = 0;
 
    // Iterate over the array
    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++;
        }
    }
 
    // Stores the difference
    int ans = 0;
 
    // Sort the positive numbers
    // in ascending order
    sort(pos.begin(), pos.end());
 
    // Sort the negative numbers
    // in decreasing order
    sort(neg.begin(), neg.end(), greater());
 
    // Case 1: Include both positive
    // and negative numbers
    if (pos.size() > 0 && neg.size() > 0) {
 
        ans = (pos_sum - neg_sum);
    }
    else if (pos.size() > 0) {
 
        if (zero > 0) {
 
            // Case 2:  When all numbers are
            // positive and array contains 0s
           
              //Put all numbers in subset A and
              //one 0 in subset B
            ans = (pos_sum);
        }
        else {
 
            // Case 3: When all numbers are positive
           
              //Put all numbers in subset A except the 
              //smallest positive number which is put in B
            ans = (pos_sum - 2 * pos[0]);
        }
    }
    else {
        if (zero > 0) {
 
            // Case 4: When all numbers are
            // negative and array contains 0s
 
            // Put all numbers in subset B
            // and one 0 in subset A
            ans = (-1 * neg_sum);
        }
        else {
            // Case 5: When all numbers are negative
 
            // Place the largest negative number
            // in subset A and remaining in B
            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;
}


Python3
# Python 3 Program for the above approach
 
def maxSumAfterPartition(arr, n):
    # Stores the positive elements
    pos = []
 
    # Stores the negative elements
    neg = []
 
    # Stores the count of 0s
    zero = 0
 
    # Sum of all positive numbers
    pos_sum = 0
 
    # Sum of all negative numbers
    neg_sum = 0
 
    # Iterate over the array
    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
 
    # Stores the difference
    ans = 0
 
    # Sort the positive numbers
    # in ascending order
    pos.sort()
 
    # Sort the negative numbers
    # in decreasing order
    neg.sort(reverse=True)
 
    # Case 1: Include both positive
    # and negative numbers
    if (len(pos) > 0 and len(neg) > 0):
 
        ans = (pos_sum - neg_sum)
    elif(len(pos) > 0):
        if (zero > 0):
 
            # Case 2:  When all numbers are
            # positive and array contains 0s
           
              #Put all numbers in subset A and
              #one 0 in subset B
            ans = (pos_sum)
        else:
 
            # Case 3: When all numbers are positive
           
              #Put all numbers in subset A except the 
              #smallest positive number which is put in B
            ans = (pos_sum - 2 * pos[0])
    else:
        if (zero > 0):
            # Case 4: When all numbers are
            # negative and array contains 0s
 
            # Put all numbers in subset B
            # and one 0 in subset A
            ans = (-1 * neg_sum)
        else:
            # Case 5: When all numbers are negative
 
            # Place the largest negative number
            # in subset A and remaining in B
            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))
     
    # This code is contributed by ipg2016107.


输出
18

时间复杂度: O(NlogN)
辅助空间: O(N)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。