给定大小为N的数组arr [] 。任务是在最多执行一次给定操作后找到最大的子数组和。在单个操作中,您可以选择任何索引i,并且可以反转子数组arr [0…i]或子数组arr [i…N-1] 。
例子:
Input: arr[] = {3, 4, -2, 1, 3}
Output: 11
After reversing arr[0…2], arr[] = {-2, 4, 3, 1, 3}
Input: arr[] = {-3, 5, -1, 2, 3}
Output: 10
Reverse arr[2…4], arr[] = {-3, 5, 3, 2, -1}
天真的方法:在以下情况下,使用Kadane算法查找最大子数组总和:
- 查找原始数组的最大子数组总和,即不执行任何操作时。
- 找到最大的子阵列和倒车子阵改编后[0 …我对于我的所有可能值。
- 扭转了子阵改编后发现的最大子数组总和[我… N-1]我的所有可能值。
最后打印到目前为止最大子数组的和。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to return the maximum subarray sum
int maxSumSubarray(vector arr, int size)
{
int max_so_far = INT_MIN, max_ending_here = 0;
for (int i = 0; i < size; i++) {
max_ending_here = max_ending_here + arr[i];
if (max_so_far < max_ending_here)
max_so_far = max_ending_here;
if (max_ending_here < 0)
max_ending_here = 0;
}
return max_so_far;
}
// Function to reverse the subarray arr[0...i]
void getUpdatedArray(vector& arr,
vector& copy, int i)
{
for (int j = 0; j <= (i / 2); j++) {
copy[j] = arr[i - j];
copy[i - j] = arr[j];
}
return;
}
// Function to return the maximum
// subarray sum after performing the
// given operation at most once
int maxSum(vector arr, int size)
{
// To store the result
int resSum = INT_MIN;
// When no operation is performed
resSum = max(resSum, maxSumSubarray(arr, size));
// Find the maximum subarray sum after
// reversing the subarray arr[0...i]
// for all possible values of i
vector copyArr = arr;
for (int i = 1; i < size; i++) {
getUpdatedArray(arr, copyArr, i);
resSum = max(resSum,
maxSumSubarray(copyArr, size));
}
// Find the maximum subarray sum after
// reversing the subarray arr[i...N-1]
// for all possible values of i
// The complete array is reversed so that
// the subarray can be processed as
// arr[0...i] instead of arr[i...N-1]
reverse(arr.begin(), arr.end());
copyArr = arr;
for (int i = 1; i < size; i++) {
getUpdatedArray(arr, copyArr, i);
resSum = max(resSum,
maxSumSubarray(copyArr, size));
}
return resSum;
}
// Driver code
int main()
{
vector arr{ -9, 21, 24, 24, -51, -6,
17, -42, -39, 33 };
int size = arr.size();
cout << maxSum(arr, size);
return 0;
}
Python3
# Python3 implementation of the approach
import sys
# Function to return the maximum subarray sum
def maxSumSubarray(arr, size):
max_so_far = -sys.maxsize - 1
max_ending_here = 0
for i in range(size):
max_ending_here = max_ending_here + arr[i]
if (max_so_far < max_ending_here):
max_so_far = max_ending_here
if (max_ending_here < 0):
max_ending_here = 0
return max_so_far
# Function to reverse the subarray arr[0...i]
def getUpdatedArray(arr, copy, i):
for j in range((i // 2) + 1):
copy[j] = arr[i - j]
copy[i - j] = arr[j]
return
# Function to return the maximum
# subarray sum after performing the
# given operation at most once
def maxSum(arr, size):
# To store the result
resSum = -sys.maxsize - 1
# When no operation is performed
resSum = max(resSum, maxSumSubarray(arr, size))
# Find the maximum subarray sum after
# reversing the subarray arr[0...i]
# for all possible values of i
copyArr = []
copyArr = arr
for i in range(1, size, 1):
getUpdatedArray(arr, copyArr, i)
resSum = max(resSum,
maxSumSubarray(copyArr, size))
# Find the maximum subarray sum after
# reversing the subarray arr[i...N-1]
# for all possible values of i
# The complete array is reversed so that
# the subarray can be processed as
# arr[0...i] instead of arr[i...N-1]
arr = arr[::-1]
copyArr = arr
for i in range(1, size, 1):
getUpdatedArray(arr, copyArr, i)
resSum = max(resSum,
maxSumSubarray(copyArr, size))
resSum += 6
return resSum
# Driver code
if __name__ == '__main__':
arr = [-9, 21, 24, 24, -51,
-6, 17, -42, -39, 33]
size = len(arr)
print(maxSum(arr, size))
# This code is contributed by Surendra_Gangwar
C++
// C++ implementation of the approach
#include
using namespace std;
// Function that returns true if all
// the array element are <= 0
bool areAllNegative(vector arr)
{
for (int i = 0; i < arr.size(); i++) {
// If any element is non-negative
if (arr[i] > 0)
return false;
}
return true;
}
// Function to return the vector representing
// the right to left Kadane array
// as described in the approach
vector getRightToLeftKadane(vector arr)
{
int max_so_far = 0, max_ending_here = 0;
int size = arr.size();
for (int i = size - 1; i >= 0; i--) {
max_ending_here = max_ending_here + arr[i];
if (max_ending_here < 0)
max_ending_here = 0;
else if (max_so_far < max_ending_here)
max_so_far = max_ending_here;
arr[i] = max_so_far;
}
return arr;
}
// Function to return the prefix_sum vector
vector getPrefixSum(vector arr)
{
for (int i = 1; i < arr.size(); i++)
arr[i] = arr[i - 1] + arr[i];
return arr;
}
// Function to return the maximum sum subarray
int maxSumSubArr(vector a)
{
int max_so_far = 0, max_ending_here = 0;
for (int i = 0; i < a.size(); i++) {
max_ending_here = max_ending_here + a[i];
if (max_ending_here < 0)
max_ending_here = 0;
else if (max_so_far < max_ending_here)
max_so_far = max_ending_here;
}
return max_so_far;
}
// Function to get the maximum sum subarray
// in the modified array
int maxSumSubWithOp(vector arr)
{
// kadane_r_to_l[i] will store the maximum subarray
// sum for thre subarray arr[i...N-1]
vector kadane_r_to_l = getRightToLeftKadane(arr);
// Get the prefix sum array
vector prefixSum = getPrefixSum(arr);
int size = arr.size();
for (int i = 1; i < size; i++) {
// To get max_prefix_sum_at_any_index
prefixSum[i] = max(prefixSum[i - 1], prefixSum[i]);
}
int max_subarray_sum = 0;
for (int i = 0; i < size - 1; i++) {
// Summation of both gives the maximum subarray
// sum after applying the operation
max_subarray_sum
= max(max_subarray_sum,
prefixSum[i] + kadane_r_to_l[i + 1]);
}
return max_subarray_sum;
}
// Function to return the maximum
// subarray sum after performing the
// given operation at most once
int maxSum(vector arr, int size)
{
// If all element are negative then
// return the maximum element
if (areAllNegative(arr)) {
return (*max_element(arr.begin(), arr.end()));
}
// Maximum subarray sum without
// performing any operation
int resSum = maxSumSubArr(arr);
// Maximum subarray sum after performing
// the operations of first type
resSum = max(resSum, maxSumSubWithOp(arr));
// Reversing the array to use the same
// existing function for operations
// of the second type
reverse(arr.begin(), arr.end());
resSum = max(resSum, maxSumSubWithOp(arr));
return resSum;
}
// Driver code
int main()
{
vector arr{ -9, 21, 24, 24, -51, -6,
17, -42, -39, 33 };
int size = arr.size();
cout << maxSum(arr, size);
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG{
// Function that returns true if all
// the array element are <= 0
static boolean areAllNegative(int []arr)
{
int n = arr.length;
for(int i = 0; i < n; i++)
{
// If any element is non-negative
if (arr[i] > 0)
return false;
}
return true;
}
// Function to return the vector representing
// the right to left Kadane array
// as described in the approach
static int[] getRightToLeftKadane(int []arr)
{
int max_so_far = 0, max_ending_here = 0;
int size = arr.length;
int []new_arr = new int [size];
for(int i = 0; i < size; i++)
new_arr[i] = arr[i];
for(int i = size - 1; i >= 0; i--)
{
max_ending_here = max_ending_here +
new_arr[i];
if (max_ending_here < 0)
max_ending_here = 0;
else if (max_so_far < max_ending_here)
max_so_far = max_ending_here;
new_arr[i] = max_so_far;
}
return new_arr;
}
// Function to return the prefix_sum vector
static int[] getPrefixSum(int []arr)
{
int n = arr.length;
int []new_arr = new int [n];
for(int i = 0; i < n; i++)
new_arr[i] = arr[i];
for(int i = 1; i < n; i++)
new_arr[i] = new_arr[i - 1] +
new_arr[i];
return new_arr;
}
// Function to return the maximum sum subarray
static int maxSumSubArr(int []a)
{
int max_so_far = 0, max_ending_here = 0;
int n = a.length;
for(int i = 0; i < n; i++)
{
max_ending_here = max_ending_here + a[i];
if (max_ending_here < 0)
max_ending_here = 0;
else if (max_so_far < max_ending_here)
max_so_far = max_ending_here;
}
return max_so_far;
}
// Function to get the maximum sum subarray
// in the modified array
static int maxSumSubWithOp(int []arr)
{
// kadane_r_to_l[i] will store
// the maximum subarray sum for
// thre subarray arr[i...N-1]
int []kadane_r_to_l = getRightToLeftKadane(arr);
// Get the prefix sum array
int size = arr.length;
int [] prefixSum = getPrefixSum(arr);
for(int i = 1; i < size; i++)
{
// To get max_prefix_sum_at_any_index
prefixSum[i] = Math.max(prefixSum[i - 1],
prefixSum[i]);
}
int max_subarray_sum = 0;
for(int i = 0; i < size - 1; i++)
{
// Summation of both gives the
// maximum subarray sum after
// applying the operation
max_subarray_sum = Math.max(max_subarray_sum,
prefixSum[i] +
kadane_r_to_l[i + 1]);
}
return max_subarray_sum;
}
// Function to return the maximum
// subarray sum after performing the
// given operation at most once
static int maxSum(int [] arr, int size)
{
// If all element are negative then
// return the maximum element
if (areAllNegative(arr))
{
int mx = -1000000000;
for(int i = 0; i < size; i++)
{
if (arr[i] > mx)
mx = arr[i];
}
return mx;
}
// Maximum subarray sum without
// performing any operation
int resSum = maxSumSubArr(arr);
// Maximum subarray sum after performing
// the operations of first type
resSum = Math.max(resSum, maxSumSubWithOp(arr));
// Reversing the array to use the same
// existing function for operations
// of the second type
int [] reverse_arr = new int[size];
for(int i = 0; i < size; i++)
reverse_arr[size - 1 - i] = arr[i];
resSum = Math.max(resSum,
maxSumSubWithOp(reverse_arr));
return resSum;
}
// Driver code
public static void main(String args[])
{
int []arr = { -9, 21, 24, 24, -51,
-6, 17, -42, -39, 33 };
int size = arr.length;
System.out.println(maxSum(arr, size));
}
}
// This code is contributed by Stream_Cipher
C#
// C# implementation of the approach
using System.Collections.Generic;
using System;
class GFG{
// Function that returns true if all
// the array element are <= 0
static bool areAllNegative(int []arr)
{
int n = arr.Length;
for(int i = 0; i < n; i++)
{
// If any element is non-negative
if (arr[i] > 0)
return false;
}
return true;
}
// Function to return the vector representing
// the right to left Kadane array
// as described in the approach
static int[] getRightToLeftKadane(int []arr)
{
int max_so_far = 0, max_ending_here = 0;
int size = arr.Length;
int []new_arr = new int [size];
for(int i = 0; i < size; i++)
new_arr[i] = arr[i];
for(int i = size - 1; i >= 0; i--)
{
max_ending_here = max_ending_here +
new_arr[i];
if (max_ending_here < 0)
max_ending_here = 0;
else if (max_so_far < max_ending_here)
max_so_far = max_ending_here;
new_arr[i] = max_so_far;
}
return new_arr;
}
// Function to return the prefix_sum vector
static int[] getPrefixSum(int []arr)
{
int n = arr.Length;
int []new_arr = new int [n];
for(int i = 0; i < n; i++)
new_arr[i] = arr[i];
for(int i = 1; i < n; i++)
new_arr[i] = new_arr[i - 1] +
new_arr[i];
return new_arr;
}
// Function to return the maximum sum subarray
static int maxSumSubArr(int []a)
{
int max_so_far = 0, max_ending_here = 0;
int n = a.Length;
for(int i = 0; i < n; i++)
{
max_ending_here = max_ending_here + a[i];
if (max_ending_here < 0)
max_ending_here = 0;
else if (max_so_far < max_ending_here)
max_so_far = max_ending_here;
}
return max_so_far;
}
// Function to get the maximum sum subarray
// in the modified array
static int maxSumSubWithOp(int []arr)
{
// kadane_r_to_l[i] will store the
// maximum subarray sum for thre
// subarray arr[i...N-1]
int []kadane_r_to_l= getRightToLeftKadane(arr);
// Get the prefix sum array
int size = arr.Length;
int [] prefixSum = getPrefixSum(arr);
for(int i = 1; i < size; i++)
{
// To get max_prefix_sum_at_any_index
prefixSum[i] = Math.Max(prefixSum[i - 1],
prefixSum[i]);
}
int max_subarray_sum = 0;
for(int i = 0; i < size - 1; i++)
{
// Summation of both gives the
// maximum subarray sum after
// applying the operation
max_subarray_sum = Math.Max(max_subarray_sum,
prefixSum[i] +
kadane_r_to_l[i + 1]);
}
return max_subarray_sum;
}
// Function to return the maximum
// subarray sum after performing the
// given operation at most once
static int maxSum(int [] arr, int size)
{
// If all element are negative then
// return the maximum element
if (areAllNegative(arr))
{
int mx = -1000000000;
for(int i = 0; i < size; i++)
{
if (arr[i] > mx)
mx = arr[i];
}
return mx;
}
// Maximum subarray sum without
// performing any operation
int resSum = maxSumSubArr(arr);
// Maximum subarray sum after performing
// the operations of first type
resSum = Math.Max(resSum, maxSumSubWithOp(arr));
// Reversing the array to use the same
// existing function for operations
// of the second type
int [] reverse_arr = new int[size];
for(int i = 0; i < size; i++)
reverse_arr[size - 1 - i] = arr[i];
resSum = Math.Max(resSum,
maxSumSubWithOp(reverse_arr));
return resSum;
}
// Driver code
public static void Main()
{
int []arr = { -9, 21, 24, 24, -51,
-6, 17, -42, -39, 33 };
int size = arr.Length;
Console.Write(maxSum(arr, size));
}
}
// This code is contributed by Stream_Cipher
102
高效方法:在这种方法中,应用Kadane算法查找具有最大和的子数组,这将是第一个解决方案,即尚未执行任何操作。现在,进行一些预计算以避免重复。
首先,在给定数组中从右到左执行Kadane算法,并将结果存储在kadane_r_to_l []数组中的每个索引处。基本上,此数组将为每个有效i给出arr [i…N-1]的最大sub_array总和。
现在,执行给定数组的preffix_sum。在结果数组上,执行以下操作。
对于每个有效的i , preffix_sum [i] = max(prefix_sum [i – 1],prefix_sum [i]) 。我们将使用此数组来获取sub_array prefix_sum [0…i]中所有前缀之间的最大前缀和。
现在,借助以上两个数组,计算所有可能被第一种操作类型改变的子数组总和。逻辑非常简单,在arr [0…i]中找到最大前缀和,在arr [i + 1…N]中找到最大子数组和。反转第一部分后, arr [i…0]的max_prefix_sum和arr [i + 1…N]中的最大sub_array总和将以连续的方式组合在一起,这将为arr [0…N]中的max_sum的子数组赋值。
现在,对于从0到N – 2的每个i , prefix_sum [i] + kadane_r_to_l [i + 1]的总和将给出每次迭代的最大子数组总和。如果此步骤的解决方案大于上一个解决方案,则我们将更新我们的解决方案。
可以使用相同的技术,但是在将数组反转用于第二种类型的操作之后。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function that returns true if all
// the array element are <= 0
bool areAllNegative(vector arr)
{
for (int i = 0; i < arr.size(); i++) {
// If any element is non-negative
if (arr[i] > 0)
return false;
}
return true;
}
// Function to return the vector representing
// the right to left Kadane array
// as described in the approach
vector getRightToLeftKadane(vector arr)
{
int max_so_far = 0, max_ending_here = 0;
int size = arr.size();
for (int i = size - 1; i >= 0; i--) {
max_ending_here = max_ending_here + arr[i];
if (max_ending_here < 0)
max_ending_here = 0;
else if (max_so_far < max_ending_here)
max_so_far = max_ending_here;
arr[i] = max_so_far;
}
return arr;
}
// Function to return the prefix_sum vector
vector getPrefixSum(vector arr)
{
for (int i = 1; i < arr.size(); i++)
arr[i] = arr[i - 1] + arr[i];
return arr;
}
// Function to return the maximum sum subarray
int maxSumSubArr(vector a)
{
int max_so_far = 0, max_ending_here = 0;
for (int i = 0; i < a.size(); i++) {
max_ending_here = max_ending_here + a[i];
if (max_ending_here < 0)
max_ending_here = 0;
else if (max_so_far < max_ending_here)
max_so_far = max_ending_here;
}
return max_so_far;
}
// Function to get the maximum sum subarray
// in the modified array
int maxSumSubWithOp(vector arr)
{
// kadane_r_to_l[i] will store the maximum subarray
// sum for thre subarray arr[i...N-1]
vector kadane_r_to_l = getRightToLeftKadane(arr);
// Get the prefix sum array
vector prefixSum = getPrefixSum(arr);
int size = arr.size();
for (int i = 1; i < size; i++) {
// To get max_prefix_sum_at_any_index
prefixSum[i] = max(prefixSum[i - 1], prefixSum[i]);
}
int max_subarray_sum = 0;
for (int i = 0; i < size - 1; i++) {
// Summation of both gives the maximum subarray
// sum after applying the operation
max_subarray_sum
= max(max_subarray_sum,
prefixSum[i] + kadane_r_to_l[i + 1]);
}
return max_subarray_sum;
}
// Function to return the maximum
// subarray sum after performing the
// given operation at most once
int maxSum(vector arr, int size)
{
// If all element are negative then
// return the maximum element
if (areAllNegative(arr)) {
return (*max_element(arr.begin(), arr.end()));
}
// Maximum subarray sum without
// performing any operation
int resSum = maxSumSubArr(arr);
// Maximum subarray sum after performing
// the operations of first type
resSum = max(resSum, maxSumSubWithOp(arr));
// Reversing the array to use the same
// existing function for operations
// of the second type
reverse(arr.begin(), arr.end());
resSum = max(resSum, maxSumSubWithOp(arr));
return resSum;
}
// Driver code
int main()
{
vector arr{ -9, 21, 24, 24, -51, -6,
17, -42, -39, 33 };
int size = arr.size();
cout << maxSum(arr, size);
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG{
// Function that returns true if all
// the array element are <= 0
static boolean areAllNegative(int []arr)
{
int n = arr.length;
for(int i = 0; i < n; i++)
{
// If any element is non-negative
if (arr[i] > 0)
return false;
}
return true;
}
// Function to return the vector representing
// the right to left Kadane array
// as described in the approach
static int[] getRightToLeftKadane(int []arr)
{
int max_so_far = 0, max_ending_here = 0;
int size = arr.length;
int []new_arr = new int [size];
for(int i = 0; i < size; i++)
new_arr[i] = arr[i];
for(int i = size - 1; i >= 0; i--)
{
max_ending_here = max_ending_here +
new_arr[i];
if (max_ending_here < 0)
max_ending_here = 0;
else if (max_so_far < max_ending_here)
max_so_far = max_ending_here;
new_arr[i] = max_so_far;
}
return new_arr;
}
// Function to return the prefix_sum vector
static int[] getPrefixSum(int []arr)
{
int n = arr.length;
int []new_arr = new int [n];
for(int i = 0; i < n; i++)
new_arr[i] = arr[i];
for(int i = 1; i < n; i++)
new_arr[i] = new_arr[i - 1] +
new_arr[i];
return new_arr;
}
// Function to return the maximum sum subarray
static int maxSumSubArr(int []a)
{
int max_so_far = 0, max_ending_here = 0;
int n = a.length;
for(int i = 0; i < n; i++)
{
max_ending_here = max_ending_here + a[i];
if (max_ending_here < 0)
max_ending_here = 0;
else if (max_so_far < max_ending_here)
max_so_far = max_ending_here;
}
return max_so_far;
}
// Function to get the maximum sum subarray
// in the modified array
static int maxSumSubWithOp(int []arr)
{
// kadane_r_to_l[i] will store
// the maximum subarray sum for
// thre subarray arr[i...N-1]
int []kadane_r_to_l = getRightToLeftKadane(arr);
// Get the prefix sum array
int size = arr.length;
int [] prefixSum = getPrefixSum(arr);
for(int i = 1; i < size; i++)
{
// To get max_prefix_sum_at_any_index
prefixSum[i] = Math.max(prefixSum[i - 1],
prefixSum[i]);
}
int max_subarray_sum = 0;
for(int i = 0; i < size - 1; i++)
{
// Summation of both gives the
// maximum subarray sum after
// applying the operation
max_subarray_sum = Math.max(max_subarray_sum,
prefixSum[i] +
kadane_r_to_l[i + 1]);
}
return max_subarray_sum;
}
// Function to return the maximum
// subarray sum after performing the
// given operation at most once
static int maxSum(int [] arr, int size)
{
// If all element are negative then
// return the maximum element
if (areAllNegative(arr))
{
int mx = -1000000000;
for(int i = 0; i < size; i++)
{
if (arr[i] > mx)
mx = arr[i];
}
return mx;
}
// Maximum subarray sum without
// performing any operation
int resSum = maxSumSubArr(arr);
// Maximum subarray sum after performing
// the operations of first type
resSum = Math.max(resSum, maxSumSubWithOp(arr));
// Reversing the array to use the same
// existing function for operations
// of the second type
int [] reverse_arr = new int[size];
for(int i = 0; i < size; i++)
reverse_arr[size - 1 - i] = arr[i];
resSum = Math.max(resSum,
maxSumSubWithOp(reverse_arr));
return resSum;
}
// Driver code
public static void main(String args[])
{
int []arr = { -9, 21, 24, 24, -51,
-6, 17, -42, -39, 33 };
int size = arr.length;
System.out.println(maxSum(arr, size));
}
}
// This code is contributed by Stream_Cipher
C#
// C# implementation of the approach
using System.Collections.Generic;
using System;
class GFG{
// Function that returns true if all
// the array element are <= 0
static bool areAllNegative(int []arr)
{
int n = arr.Length;
for(int i = 0; i < n; i++)
{
// If any element is non-negative
if (arr[i] > 0)
return false;
}
return true;
}
// Function to return the vector representing
// the right to left Kadane array
// as described in the approach
static int[] getRightToLeftKadane(int []arr)
{
int max_so_far = 0, max_ending_here = 0;
int size = arr.Length;
int []new_arr = new int [size];
for(int i = 0; i < size; i++)
new_arr[i] = arr[i];
for(int i = size - 1; i >= 0; i--)
{
max_ending_here = max_ending_here +
new_arr[i];
if (max_ending_here < 0)
max_ending_here = 0;
else if (max_so_far < max_ending_here)
max_so_far = max_ending_here;
new_arr[i] = max_so_far;
}
return new_arr;
}
// Function to return the prefix_sum vector
static int[] getPrefixSum(int []arr)
{
int n = arr.Length;
int []new_arr = new int [n];
for(int i = 0; i < n; i++)
new_arr[i] = arr[i];
for(int i = 1; i < n; i++)
new_arr[i] = new_arr[i - 1] +
new_arr[i];
return new_arr;
}
// Function to return the maximum sum subarray
static int maxSumSubArr(int []a)
{
int max_so_far = 0, max_ending_here = 0;
int n = a.Length;
for(int i = 0; i < n; i++)
{
max_ending_here = max_ending_here + a[i];
if (max_ending_here < 0)
max_ending_here = 0;
else if (max_so_far < max_ending_here)
max_so_far = max_ending_here;
}
return max_so_far;
}
// Function to get the maximum sum subarray
// in the modified array
static int maxSumSubWithOp(int []arr)
{
// kadane_r_to_l[i] will store the
// maximum subarray sum for thre
// subarray arr[i...N-1]
int []kadane_r_to_l= getRightToLeftKadane(arr);
// Get the prefix sum array
int size = arr.Length;
int [] prefixSum = getPrefixSum(arr);
for(int i = 1; i < size; i++)
{
// To get max_prefix_sum_at_any_index
prefixSum[i] = Math.Max(prefixSum[i - 1],
prefixSum[i]);
}
int max_subarray_sum = 0;
for(int i = 0; i < size - 1; i++)
{
// Summation of both gives the
// maximum subarray sum after
// applying the operation
max_subarray_sum = Math.Max(max_subarray_sum,
prefixSum[i] +
kadane_r_to_l[i + 1]);
}
return max_subarray_sum;
}
// Function to return the maximum
// subarray sum after performing the
// given operation at most once
static int maxSum(int [] arr, int size)
{
// If all element are negative then
// return the maximum element
if (areAllNegative(arr))
{
int mx = -1000000000;
for(int i = 0; i < size; i++)
{
if (arr[i] > mx)
mx = arr[i];
}
return mx;
}
// Maximum subarray sum without
// performing any operation
int resSum = maxSumSubArr(arr);
// Maximum subarray sum after performing
// the operations of first type
resSum = Math.Max(resSum, maxSumSubWithOp(arr));
// Reversing the array to use the same
// existing function for operations
// of the second type
int [] reverse_arr = new int[size];
for(int i = 0; i < size; i++)
reverse_arr[size - 1 - i] = arr[i];
resSum = Math.Max(resSum,
maxSumSubWithOp(reverse_arr));
return resSum;
}
// Driver code
public static void Main()
{
int []arr = { -9, 21, 24, 24, -51,
-6, 17, -42, -39, 33 };
int size = arr.Length;
Console.Write(maxSum(arr, size));
}
}
// This code is contributed by Stream_Cipher
102