给定一个由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
Javascript
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
Javascript
8
时间复杂度: O(N 2 )
辅助空间: O(1)
高效的方法:从上面的方法可以看出,要获得最大的数组和, (2 * subarray sum)需要对所有子数组进行最大化。这可以通过使用动态规划来完成。以下是步骤:
- 创建一个新数组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));
}
}
蟒蛇3
# 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
Javascript
8
时间复杂度: O(N)
辅助空间: O(1)
笔记: 也可以通过找到最小子数组和并打印 max(TotalSum, TotalSum-2*(minsubarraysum)) 来完成
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live