📜  改变数组后的最大和子数组

📅  最后修改于: 2021-09-17 06:48:43             🧑  作者: Mango

给定一个大小为N的数组arr[] 。任务是在最多执行一次给定操作后找到可能的最大子数组和。在单个操作中,您可以选择任何索引i,并且可以反转子数组 arr[0…i]或子数组 arr[i…N-1]

例子:

朴素的方法:使用 Kadane 算法在以下情况下找到最大子数组和:

  1. 找到原始数组的最大子数组和,即当没有执行任何操作时。
  2. 找到最大的子阵列和倒车子阵改编[0 …我对于的所有可能值。
  3. 扭转了子阵改编后发现的最大子数组总和[我… 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


Javascript


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


Javascript


输出:
102

高效的方法:在这种方法中,应用 Kadane 的算法来找到具有最大和的子数组,这将是第一个解决方案,即尚未执行任何操作。现在,做一些预计算以避免重复。
首先,在给定数组中从右到左执行 Kadane 算法,并将结果存储在kadane_r_to_l[]数组中的每个索引处。基本上,这个数组将为每个有效i提供arr[i…N-1]的最大 sub_array 总和。
现在,执行给定数组的 prefix_sum。在结果数组上,执行以下操作。
对于每个有效的ipreffix_sum[i] = max(prefix_sum[i – 1], prefix_sum[i]) 。我们将使用这个数组来获取 sub_array prefix_sum[0…i]中所有前缀中的最大前缀和。
现在借助上述两个数组,计算所有可能被第一种操作改变的子数组和。逻辑很简单,求arr[0…i] 中的最大前缀和和arr[i+1…N] 中的最大 sub_array 和。在反转第一部分之后, arr[i…0] 的max_prefix_sum 和arr[i+1…N] 中的最大子数组和将以连续的方式放在一起,这将使子数组在arr[0…N] 中具有 max_sum。
现在对于从0N – 2 的每个iprefix_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

Javascript


输出:
102

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

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