给定N个整数的数组arr [] ,任务是找到最多可以通过翻转给定数组的任何子数组的符号一次而获得的数组的最大和。
例子:
Input: arr[] = {-2, 3, -1, -4, -2}
Output: 8
Explanation:
Flipping the signs of subarray {-1, -4, -2} modifies the array to {-2, 3, 1, 4, 2}. Therefore, the sum of the array = -2 + 3 + 1 + 4 + 2 = 8, which is the maximum possible.
Input: arr[] = {1, 2, -10, 2, -20}
Output: 31
Explanation:
Flipping the signs of subarray {-10, 2, -20} modifies the array to {1, 2, 10, -2, 20}. Therefore, the sum of the array = 1 + 2 + 10 – 2 + 20 = 31, which is the maximum possible.
天真的方法:最简单的方法是计算数组的总和,然后生成所有可能的子数组。现在,对于每个子数组{ A [i],…A [j] },从总和中减去其总和sum(A [i],…,A [j])并翻转子数组元素的符号。翻转子数组后,将翻转后的子数组的总和(即(-1 * sum(A [i],…,A [j])))添加到总和中。步骤如下:
- 找到原始数组的总和(例如total_sum )并将其存储。
- 现在,对于所有可能的子数组,找到total_sum的最大值– 2 * sum(i,j) 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the maximum sum
// after flipping a subarray
int maxSumFlip(int a[], int n)
{
// Stores the total sum of array
int total_sum = 0;
for (int i = 0; i < n; i++)
total_sum += a[i];
// Initialize the maximum sum
int max_sum = INT_MIN;
// Iterate over all possible subarrays
for (int i = 0; i < n; i++)
{
// Initialize sum of the subarray
// before flipping sign
int sum = 0;
// Initialize sum of subarray
// after flipping sign
int flip_sum = 0;
for (int j = i; j < n; j++)
{
// Calculate the sum of
// original subarray
sum += a[j];
// Subtract the original
// subarray sum and add
// the flipped subarray
// sum to the total sum
max_sum = max(max_sum, total_sum - 2 * sum);
}
}
// Return the max_sum
return max(max_sum, total_sum);
}
// Driver Code
int main()
{
int arr[] = { -2, 3, -1, -4, -2 };
int N = sizeof(arr) / sizeof(int);
cout << maxSumFlip(arr, N);
}
// This code is contributed by sanjoy_62
Java
// Java program for the above approach
import java.io.*;
public class GFG
{
// Function to find the maximum sum
// after flipping a subarray
public static int maxSumFlip(int a[], int n)
{
// Stores the total sum of array
int total_sum = 0;
for (int i = 0; i < n; i++)
total_sum += a[i];
// Initialize the maximum sum
int max_sum = Integer.MIN_VALUE;
// Iterate over all possible subarrays
for (int i = 0; i < n; i++)
{
// Initialize sum of the subarray
// before flipping sign
int sum = 0;
// Initialize sum of subarray
// after flipping sign
int flip_sum = 0;
for (int j = i; j < n; j++)
{
// Calculate the sum of
// original subarray
sum += a[j];
// Subtract the original
// subarray sum and add
// the flipped subarray
// sum to the total sum
max_sum = Math.max(max_sum,
total_sum - 2 * sum);
}
}
// Return the max_sum
return Math.max(max_sum, total_sum);
}
// Driver Code
public static void main(String args[])
{
int arr[] = { -2, 3, -1, -4, -2 };
int N = arr.length;
// Function call
System.out.println(maxSumFlip(arr, N));
}
}
Python3
# Python3 program for the above approach
import sys
# Function to find the maximum sum
# after flipping a subarray
def maxSumFlip(a, n):
# Stores the total sum of array
total_sum = 0
for i in range(n):
total_sum += a[i]
# Initialize the maximum sum
max_sum = -sys.maxsize - 1
# Iterate over all possible subarrays
for i in range(n):
# Initialize sum of the subarray
# before flipping sign
sum = 0
# Initialize sum of subarray
# after flipping sign
flip_sum = 0
for j in range(i, n):
# Calculate the sum of
# original subarray
sum += a[j]
# Subtract the original
# subarray sum and add
# the flipped subarray
# sum to the total sum
max_sum = max(max_sum,
total_sum - 2 * sum)
# Return the max_sum
return max(max_sum, total_sum)
# Driver Code
arr = [-2, 3, -1, -4, -2]
N = len(arr)
print(maxSumFlip(arr, N))
# This code is contributed by sanjoy_62
C#
// C# program for the above approach
using System;
class GFG {
// Function to find the maximum sum
// after flipping a subarray
public static int maxSumFlip(int[] a, int n)
{
// Stores the total sum of array
int total_sum = 0;
for (int i = 0; i < n; i++)
total_sum += a[i];
// Initialize the maximum sum
int max_sum = int.MinValue;
// Iterate over all possible subarrays
for (int i = 0; i < n; i++)
{
// Initialize sum of the subarray
// before flipping sign
int sum = 0;
// Initialize sum of subarray
// after flipping sign
// int flip_sum = 0;
for (int j = i; j < n; j++)
{
// Calculate the sum of
// original subarray
sum += a[j];
// Subtract the original
// subarray sum and add
// the flipped subarray
// sum to the total sum
max_sum = Math.Max(max_sum,
total_sum - 2 * sum);
}
}
// Return the max_sum
return Math.Max(max_sum, total_sum);
}
// Driver Code
public static void Main(String[] args)
{
int[] arr = { -2, 3, -1, -4, -2 };
int N = arr.Length;
// Function call
Console.WriteLine(maxSumFlip(arr, N));
}
}
// This code is contributed by 29AjayKumar
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the maximum sum
// after flipping a subarray
int maxSumFlip(int a[], int n)
{
// Find the total sum of array
int total_sum = 0;
for (int i = 0; i < n; i++)
total_sum += a[i];
// Using Kadane's Algorithm
int max_ending_here = -a[0] - a[0];
int curr_sum = -a[0] - a[0];
for (int i = 1; i < n; i++)
{
// Either extend previous
// sub_array or start
// new subarray
curr_sum = max(curr_sum + (-a[i] - a[i]),
(-a[i] - a[i]));
// Keep track of max_sum array
max_ending_here = max(max_ending_here, curr_sum);
}
// Add the sum to the total_sum
int max_sum = total_sum + max_ending_here;
// Check max_sum was maximum
// with flip or without flip
max_sum = max(max_sum, total_sum);
// Return max_sum
return max_sum;
}
// Driver code
int main()
{
int arr[] = { -2, 3, -1, -4, -2 };
int N = sizeof(arr) / sizeof(arr[0]);
// Function call
cout << maxSumFlip(arr, N) << endl;
return 0;
}
// This code is contributed by divyeshrabadiya07
Java
// Java program for the above approach
import java.util.*;
public class Main {
// Function to find the maximum sum
// after flipping a subarray
public static int maxSumFlip(int a[], int n)
{
// Find the total sum of array
int total_sum = 0;
for (int i = 0; i < n; i++)
total_sum += a[i];
// Using Kadane's Algorithm
int max_ending_here = -a[0] - a[0];
int curr_sum = -a[0] - a[0];
for (int i = 1; i < n; i++)
{
// Either extend previous
// sub_array or start
// new subarray
curr_sum = Math.max(curr_sum + (-a[i] - a[i]),
(-a[i] - a[i]));
// Keep track of max_sum array
max_ending_here
= Math.max(max_ending_here, curr_sum);
}
// Add the sum to the total_sum
int max_sum = total_sum + max_ending_here;
// Check max_sum was maximum
// with flip or without flip
max_sum = Math.max(max_sum, total_sum);
// Return max_sum
return max_sum;
}
// Driver Code
public static void main(String args[])
{
int arr[] = { -2, 3, -1, -4, -2 };
int N = arr.length;
// Function Call
System.out.println(maxSumFlip(arr, N));
}
}
Python3
# Python3 program for the above approach
# Function to find the maximum sum
# after flipping a subarray
def maxSumFlip(a, n):
# Find the total sum of array
total_sum = 0
for i in range(n):
total_sum += a[i]
# Using Kadane's Algorithm
max_ending_here = -a[0] - a[0]
curr_sum = -a[0] - a[0]
for i in range(1, n, 1):
# Either extend previous
# sub_array or start
# new subarray
curr_sum = max(curr_sum + (-a[i] - a[i]),
(-a[i] - a[i]))
# Keep track of max_sum array
max_ending_here = max(max_ending_here,
curr_sum)
# Add the sum to the total_sum
max_sum = total_sum + max_ending_here
# Check max_sum was maximum
# with flip or without flip
max_sum = max(max_sum, total_sum)
# Return max_sum
return max_sum
# Driver code
if __name__ == '__main__':
arr = [ -2, 3, -1, -4, -2 ]
N = len(arr)
# Function call
print(maxSumFlip(arr, N))
# This code is contributed by Surendra_Gangwar
C#
// C# program for the above approach
using System;
class GFG {
// Function to find the maximum sum
// after flipping a subarray
public static int maxSumFlip(int[] a, int n)
{
// Find the total sum of array
int total_sum = 0;
for (int i = 0; i < n; i++)
total_sum += a[i];
// Using Kadane's Algorithm
int max_ending_here = -a[0] - a[0];
int curr_sum = -a[0] - a[0];
for (int i = 1; i < n; i++)
{
// Either extend previous
// sub_array or start
// new subarray
curr_sum = Math.Max(curr_sum + (-a[i] - a[i]),
(-a[i] - a[i]));
// Keep track of max_sum array
max_ending_here
= Math.Max(max_ending_here, curr_sum);
}
// Add the sum to the total_sum
int max_sum = total_sum + max_ending_here;
// Check max_sum was maximum
// with flip or without flip
max_sum = Math.Max(max_sum, total_sum);
// Return max_sum
return max_sum;
}
// Driver Code
public static void Main(String[] args)
{
int[] arr = { -2, 3, -1, -4, -2 };
int N = arr.Length;
// Function call
Console.WriteLine(maxSumFlip(arr, N));
}
}
// This code is contributed by 29AjayKumar
8
时间复杂度: O(N 2 )
辅助空间: O(1)
高效方法:通过上述方法,可以观察到,要获得最大数组和,需要为所有子数组最大化(2 *子数组和) 。这可以通过使用动态编程来完成。步骤如下:
- 创建一个新数组brr [] ,其中brr [i] =(-1 * arr [i])– arr [i]
- 使用Kadane算法从brr []中找到最大和子数组
- 这将使所有子数组的(2 * sum)贡献最大化。
- 将最大贡献添加到数组的总和中。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the maximum sum
// after flipping a subarray
int maxSumFlip(int a[], int n)
{
// Find the total sum of array
int total_sum = 0;
for (int i = 0; i < n; i++)
total_sum += a[i];
// Using Kadane's Algorithm
int max_ending_here = -a[0] - a[0];
int curr_sum = -a[0] - a[0];
for (int i = 1; i < n; i++)
{
// Either extend previous
// sub_array or start
// new subarray
curr_sum = max(curr_sum + (-a[i] - a[i]),
(-a[i] - a[i]));
// Keep track of max_sum array
max_ending_here = max(max_ending_here, curr_sum);
}
// Add the sum to the total_sum
int max_sum = total_sum + max_ending_here;
// Check max_sum was maximum
// with flip or without flip
max_sum = max(max_sum, total_sum);
// Return max_sum
return max_sum;
}
// Driver code
int main()
{
int arr[] = { -2, 3, -1, -4, -2 };
int N = sizeof(arr) / sizeof(arr[0]);
// Function call
cout << maxSumFlip(arr, N) << endl;
return 0;
}
// This code is contributed by divyeshrabadiya07
Java
// Java program for the above approach
import java.util.*;
public class Main {
// Function to find the maximum sum
// after flipping a subarray
public static int maxSumFlip(int a[], int n)
{
// Find the total sum of array
int total_sum = 0;
for (int i = 0; i < n; i++)
total_sum += a[i];
// Using Kadane's Algorithm
int max_ending_here = -a[0] - a[0];
int curr_sum = -a[0] - a[0];
for (int i = 1; i < n; i++)
{
// Either extend previous
// sub_array or start
// new subarray
curr_sum = Math.max(curr_sum + (-a[i] - a[i]),
(-a[i] - a[i]));
// Keep track of max_sum array
max_ending_here
= Math.max(max_ending_here, curr_sum);
}
// Add the sum to the total_sum
int max_sum = total_sum + max_ending_here;
// Check max_sum was maximum
// with flip or without flip
max_sum = Math.max(max_sum, total_sum);
// Return max_sum
return max_sum;
}
// Driver Code
public static void main(String args[])
{
int arr[] = { -2, 3, -1, -4, -2 };
int N = arr.length;
// Function Call
System.out.println(maxSumFlip(arr, N));
}
}
Python3
# Python3 program for the above approach
# Function to find the maximum sum
# after flipping a subarray
def maxSumFlip(a, n):
# Find the total sum of array
total_sum = 0
for i in range(n):
total_sum += a[i]
# Using Kadane's Algorithm
max_ending_here = -a[0] - a[0]
curr_sum = -a[0] - a[0]
for i in range(1, n, 1):
# Either extend previous
# sub_array or start
# new subarray
curr_sum = max(curr_sum + (-a[i] - a[i]),
(-a[i] - a[i]))
# Keep track of max_sum array
max_ending_here = max(max_ending_here,
curr_sum)
# Add the sum to the total_sum
max_sum = total_sum + max_ending_here
# Check max_sum was maximum
# with flip or without flip
max_sum = max(max_sum, total_sum)
# Return max_sum
return max_sum
# Driver code
if __name__ == '__main__':
arr = [ -2, 3, -1, -4, -2 ]
N = len(arr)
# Function call
print(maxSumFlip(arr, N))
# This code is contributed by Surendra_Gangwar
C#
// C# program for the above approach
using System;
class GFG {
// Function to find the maximum sum
// after flipping a subarray
public static int maxSumFlip(int[] a, int n)
{
// Find the total sum of array
int total_sum = 0;
for (int i = 0; i < n; i++)
total_sum += a[i];
// Using Kadane's Algorithm
int max_ending_here = -a[0] - a[0];
int curr_sum = -a[0] - a[0];
for (int i = 1; i < n; i++)
{
// Either extend previous
// sub_array or start
// new subarray
curr_sum = Math.Max(curr_sum + (-a[i] - a[i]),
(-a[i] - a[i]));
// Keep track of max_sum array
max_ending_here
= Math.Max(max_ending_here, curr_sum);
}
// Add the sum to the total_sum
int max_sum = total_sum + max_ending_here;
// Check max_sum was maximum
// with flip or without flip
max_sum = Math.Max(max_sum, total_sum);
// Return max_sum
return max_sum;
}
// Driver Code
public static void Main(String[] args)
{
int[] arr = { -2, 3, -1, -4, -2 };
int N = arr.Length;
// Function call
Console.WriteLine(maxSumFlip(arr, N));
}
}
// This code is contributed by 29AjayKumar
8
时间复杂度: O(N)
辅助空间: O(1)
笔记: 也可以通过找到最小子数组总和并打印max(TotalSum,TotalSum-2 *(minsubarraysum))来完成