给定一个由N个整数组成的数组A [] ,如果包含了数组的第一个元素,则所有元素的和都为负,则任务是找到可能的最大子集和。也可以考虑一个空子集(总和为0)。
例子:
Input: N = 5, A[] = {1, 10, 4, -6, 3}
Output: 17
Explanation:
On excluding A[0], subset with maximum sum = {10, 4, 3}, Sum = (10+4+3) = 17
On including A[0], subset with maximum sum = {1, -6}, Sum = (1 + (-6)) = -5, on negating -(-5) = 5
Maximum of the above two sum is max(17, 5) = 17
Input: N = 4, A[] = {3, -5, 1, -6}
Output: 8
Explanation:
On excluding A[0], subset with maximum sum = {1}, Sum = 1
On including A[0], subset with maximum sum = {3, -5, -6}, Sum = (3 + (-5) + (-6)) = -8, on negating -(-8) = 8
Maximum of the above two sum is max(1, 8) = 8
天真的方法:
解决问题的最简单方法是从数组中生成所有可能的子集,并通过将第一个元素作为每个子集的一部分来找到最大子集和maxSum和最小子集和minSum 。最后,输出maxSum和-(minSum)的最大值。
时间复杂度: O(2 N )
辅助空间: O(N)
高效方法:
要优化上述方法,请考虑以下两种情况:
- 排除第一个元素,只需从给定数组中找到所有正整数的和(例如maxSum1) 。
- 取反除A [0]以外的所有元素,然后从数组中找到所有正整数的和(例如maxSum2),然后取反,并将A [0]加到和中。
- 打印maxSum1和-maxSum2的最大值作为所需答案。
下面列出了每种情况的详细步骤:
情况1:排除第一个元素A [0]
- 从A [1]迭代到A [N-1]。
- 维护变量maxSum1 ,以跟踪最大总和,初始设置为0。
- 如果遇到正数元素(A [i]> 0) ,则将其包括在子集中,并且maxSum1将为(maxSum1 + A [i]) 。
- 最后,返回maxSum1。
情况2:包含第一个元素A [0]
- 由于在包括第一个元素时,整个总和将被求反,因此找到可能的最小总和,不包括A [0]。
- 可以使用情况1中相同的步骤获得最小值,但值为负。
- 取反从A [1]到A [N-1]的所有值。
- 执行与案例1相同的步骤。
- 一旦获得总和(例如maxSum2 ),则求和 和 向其添加A [0]。
- 再次取反maxSum2。
最后, maximum(maxSum1,maxsum2)将是必需的答案。
下面是上述方法的实现:
C++
// C++ Program to implement
// the above approach
#include
using namespace std;
// Function returns maximum subset sum
// from the given array=
int maxSubset(vector& A, bool flag)
{
int n = A.size();
int sum = 0;
// Case 2: Negate values
// from A[1] to A[N-1]
if (flag) {
for (int i = 1; i < n; i++)
A[i] = -A[i];
}
for (int i = 1; i < n; i++) {
// Include only positives
// for max subset sum
if (A[i] > 0) {
sum += A[i];
}
}
// Return max sum obtained
return sum;
}
// Function to return maximum of the
// maximum subset sum calculated
// for the two cases
int findBest(vector A)
{
// Case 1
int x = maxSubset(A, 0);
// Case 2
int y = maxSubset(A, 1);
// Modifying the sum
y = -y;
// Including first element
y += A[0];
// Negating again
y = -y;
// Return the required answer
return max(x, y);
}
// Driver Code
int main()
{
vector A = { 1, 10, 4, -6, 3 };
cout << findBest(A) << endl;
return 0;
}
Java
// Java Program to implement
// the above approach
import java.util.*;
class GFG{
// Function returns maximum subset sum
// from the given array=
static int maxSubset(int []A, boolean flag)
{
int n = A.length;
int sum = 0;
// Case 2: Negate values
// from A[1] to A[N-1]
if (flag)
{
for (int i = 1; i < n; i++)
A[i] = -A[i];
}
for (int i = 1; i < n; i++)
{
// Include only positives
// for max subset sum
if (A[i] > 0)
{
sum += A[i];
}
}
// Return max sum obtained
return sum;
}
// Function to return maximum of the
// maximum subset sum calculated
// for the two cases
static int findBest(int []A)
{
// Case 1
int x = maxSubset(A, false);
// Case 2
int y = maxSubset(A, true);
// Modifying the sum
y = -y;
// Including first element
y += A[0];
// Negating again
y = -y;
// Return the required answer
return Math.max(x, y);
}
// Driver Code
public static void main(String[] args)
{
int []A = {1, 10, 4, -6, 3};
System.out.print(findBest(A) + "\n");
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 program to implement
# the above approach
# Function returns maximum subset
# sum from the given array=
def maxSubset(A, flag):
n = len(A)
sum = 0;
# Case 2: Negate values
# from A[1] to A[N-1]
if (flag):
for i in range(1, n):
A[i] = -A[i]
for i in range(1, n):
# Include only positives
# for max subset sum
if (A[i] > 0):
sum += A[i]
# Return max sum obtained
return sum
# Function to return maximum of the
# maximum subset sum calculated
# for the two cases
def findBest(A):
# Case 1
x = maxSubset(A, 0)
# Case 2
y = maxSubset(A, 1)
# Modifying the sum
y = -y
# Including first element
y += A[0]
# Negating again
y = -y
# Return the required answer
return max(x, y)
# Driver Code
if __name__ == "__main__":
A = [ 1, 10, 4, -6, 3 ]
print (findBest(A))
# This code is contributed by chitranayal
C#
// C# Program to implement
// the above approach
using System;
class GFG{
// Function returns maximum
// subset sum from the given array
static int maxSubset(int []A,
bool flag)
{
int n = A.Length;
int sum = 0;
// Case 2: Negate values
// from A[1] to A[N-1]
if (flag)
{
for (int i = 1; i < n; i++)
A[i] = -A[i];
}
for (int i = 1; i < n; i++)
{
// Include only positives
// for max subset sum
if (A[i] > 0)
{
sum += A[i];
}
}
// Return max sum obtained
return sum;
}
// Function to return maximum of the
// maximum subset sum calculated
// for the two cases
static int findBest(int []A)
{
// Case 1
int x = maxSubset(A, false);
// Case 2
int y = maxSubset(A, true);
// Modifying the sum
y = -y;
// Including first element
y += A[0];
// Negating again
y = -y;
// Return the required answer
return Math.Max(x, y);
}
// Driver Code
public static void Main(String[] args)
{
int []A = {1, 10, 4, -6, 3};
Console.Write(findBest(A) + "\n");
}
}
// This code is contributed by 29AjayKumar
17
时间复杂度: O(N)
辅助空间: O(1)