📜  最大和子数组最多删除一个元素

📅  最后修改于: 2021-05-06 21:52:48             🧑  作者: Mango

给定一个数组,我们需要找到最大和子数组,也可以删除一个元素以获得最大和。

例子 :

Input  : arr[] = {1, 2, 3, -4, 5}
Output : 11
Explanation : We can get maximum sum subarray by
removing -4.

Input  : arr[] = [-2, -3, 4, -1, -2, 1, 5, -3]
Output : 9
Explanation : We can get maximum sum subarray by
removing -2 as, [4, -1, 1, 5] summing 9, which is 
the maximum achievable sum.

如果不应用元素删除条件,我们可以使用Kadane算法解决此问题,但是在这里也可以删除一个元素以增加最大和。可以使用两个数组(前向数组和后向数组)来处理这种情况,这些数组分别存储从开始到第ith个索引以及从第ith个索引到结束的当前最大子数组总和。
在下面的代码中,写入了两个循环,第一个循环在fw []中存储正向的最大电流总和,而另一个循环在bw []中存储反向的最大电流总和。获取当前的最大值和更新与Kadane的算法相同。
现在,当创建两个数组时,我们可以将它们用于一个元素移除条件,如下所示,在每个索引i处,忽略第i个元素后的最大子数组总和将为fw [i-1] + bw [i + 1],因此我们为所有可能的i值循环,我们在其中选择最大值。

解决方案的总时间复杂度和空间复杂度为O(N)

C++
// C++ program to get maximum sum subarray removing
// at-most one element
#include 
using namespace std;
 
// Method returns maximum sum of all subarray where
// removing one element is also allowed
int maxSumSubarrayRemovingOneEle(int arr[], int n)
{
    // Maximum sum subarrays in forward and backward
    // directions
    int fw[n], bw[n];
 
    // Initialize current max and max so far.
    int cur_max = arr[0], max_so_far = arr[0];
 
    // calculating maximum sum subarrays in forward
    // direction
    fw[0] = arr[0];
    for (int i = 1; i < n; i++)
    {
        cur_max = max(arr[i], cur_max + arr[i]);
        max_so_far = max(max_so_far, cur_max);
 
        // storing current maximum till ith, in
        // forward array
        fw[i] = cur_max;
    }
 
    // calculating maximum sum subarrays in backward
    // direction
    cur_max = max_so_far = bw[n-1] = arr[n-1];
    for (int i = n-2; i >= 0; i--)
    {
        cur_max = max(arr[i], cur_max + arr[i]);
        max_so_far = max(max_so_far, cur_max);
 
        // storing current maximum from ith, in
        // backward array
        bw[i] = cur_max;
    }
 
    /* Initializing final ans by max_so_far so that,
        case when no element is removed to get max sum
        subarray is also handled */
    int fans = max_so_far;
 
    // choosing maximum ignoring ith element
    for (int i = 1; i < n - 1; i++)
        fans = max(fans,max(0, fw[i - 1]) +max(0, bw[i + 1]));
  // In this condition we are checking when removing the ith element
  //so checking the max(0,left)+max(0,right), because maybe left<0 || right<0 so it wont contribute to the answer
        if(fans==0){
          // if no positive element in array so return max_element
            return *max_element(arr,arr+n);
        }
    return fans;
 
}
 
// Driver code to test above methods
int main()
{
    int arr[] = {-2, -3, 4, -1, -2, 1, 5, -3};
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << maxSumSubarrayRemovingOneEle(arr, n);
    return 0;
}


Java
// Java program to get maximum sum subarray
// removing at-most one element
class GFG {
     
    // Method returns maximum sum of all subarray where
    // removing one element is also allowed
    static int maxSumSubarrayRemovingOneEle(int arr[],
                                                 int n)
    {
         
        // Maximum sum subarrays in forward and
        // backward directions
        int fw[] = new int[n];
        int bw[] = new int[n];
 
        // Initialize current max and max so far.
        int cur_max = arr[0], max_so_far = arr[0];
 
        // calculating maximum sum subarrays in forward
        // direction
        fw[0] = arr[0];
 
        for (int i = 1; i < n; i++) {
 
            cur_max = Math.max(arr[i], cur_max + arr[i]);
            max_so_far = Math.max(max_so_far, cur_max);
 
            // storing current maximum till ith, in
            // forward array
            fw[i] = cur_max;
        }
 
        // calculating maximum sum subarrays in backward
        // direction
        cur_max = max_so_far = bw[n - 1] = arr[n - 1];
         
        for (int i = n - 2; i >= 0; i--) {
 
            cur_max = Math.max(arr[i], cur_max + arr[i]);
            max_so_far = Math.max(max_so_far, cur_max);
 
            // storing current maximum from ith, in
            // backward array
            bw[i] = cur_max;
        }
 
        /* Initializing final ans by max_so_far so that,
        case when no element is removed to get max sum
        subarray is also handled */
        int fans = max_so_far;
 
        // choosing maximum ignoring ith element
        for (int i = 1; i < n - 1; i++)
            fans = Math.max(fans, fw[i - 1] + bw[i + 1]);
 
        return fans;
    }
     
    // Driver code
    public static void main(String arg[])
    {
        int arr[] = { -2, -3, 4, -1, -2, 1, 5, -3 };
        int n = arr.length;
         
        System.out.print(maxSumSubarrayRemovingOneEle(
                                             arr, n));
    }
}
 
// This code is contributed by Anant Agarwal.


Python
# Python program to get maximum sum subarray removing
# at-most one element
 
# Method returns maximum sum of all subarray where
# removing one element is also allowed
def maxSumSubarrayRemovingOneEle(arr, n):
    # Maximum sum subarrays in forward and backward
    # directions
    fw = [0 for k in range(n)]
    bw = [0 for k in range(n)]
  
    # Initialize current max and max so far.
    cur_max, max_so_far = arr[0], arr[0]
    fw[0] = cur_max
  
    # calculating maximum sum subarrays in forward
    # direction
    for i in range(1,n):
        cur_max = max(arr[i], cur_max + arr[i])
        max_so_far = max(max_so_far, cur_max)
  
        # storing current maximum till ith, in
        # forward array
        fw[i] = cur_max
  
    # calculating maximum sum subarrays in backward
    # direction
    cur_max = max_so_far = bw[n-1] = arr[n-1]
    i = n-2
    while i >= 0:
        cur_max = max(arr[i], cur_max + arr[i])
        max_so_far = max(max_so_far, cur_max)
  
        # storing current maximum from ith, in
        # backward array
        bw[i] = cur_max
        i -= 1
  
    #  Initializing final ans by max_so_far so that,
    #  case when no element is removed to get max sum
    #  subarray is also handled
    fans = max_so_far
  
    #  choosing maximum ignoring ith element
    for i in range(1,n-1):
        fans = max(fans, fw[i - 1] + bw[i + 1])
  
    return fans
  
#  Driver code to test above methods
arr = [-2, -3, 4, -1, -2, 1, 5, -3]
n = len(arr)
print  maxSumSubarrayRemovingOneEle(arr, n)
 
# Contributed by: Afzal_Saan


C#
// C# program to get maximum sum subarray
// removing at-most one element
using System;
class GFG {
     
    // Method returns maximum sum of all subarray where
    // removing one element is also allowed
    static int maxSumSubarrayRemovingOneEle(int []arr,
                                                int n)
    {
         
        // Maximum sum subarrays in forward and
        // backward directions
        int []fw = new int[n];
        int []bw = new int[n];
 
        // Initialize current max and max so far.
        int cur_max = arr[0], max_so_far = arr[0];
 
        // calculating maximum sum subarrays in forward
        // direction
        fw[0] = arr[0];
 
        for (int i = 1; i < n; i++) {
 
            cur_max = Math.Max(arr[i], cur_max + arr[i]);
            max_so_far = Math.Max(max_so_far, cur_max);
 
            // storing current maximum till ith, in
            // forward array
            fw[i] = cur_max;
        }
 
        // calculating maximum sum subarrays in backward
        // direction
        cur_max = max_so_far = bw[n - 1] = arr[n - 1];
         
        for (int i = n - 2; i >= 0; i--) {
 
            cur_max = Math.Max(arr[i], cur_max + arr[i]);
            max_so_far = Math.Max(max_so_far, cur_max);
 
            // storing current maximum from ith, in
            // backward array
            bw[i] = cur_max;
        }
 
        /* Initializing final ans by max_so_far so that,
        case when no element is removed to get max sum
        subarray is also handled */
        int fans = max_so_far;
 
        // choosing maximum ignoring ith element
        for (int i = 1; i < n - 1; i++)
            fans = Math.Max(fans, fw[i - 1] + bw[i + 1]);
 
        return fans;
    }
     
    // Driver code
    public static void Main()
    {
        int []arr = { -2, -3, 4, -1, -2, 1, 5, -3 };
        int n = arr.Length;
         
        Console.WriteLine(maxSumSubarrayRemovingOneEle(
                                            arr, n));
    }
}
 
// This code is contributed by anuj_67.


PHP
= 0; $i--)
    {
        $cur_max = max($arr[$i],
                       $cur_max + $arr[$i]);
        $max_so_far = max($max_so_far,
                          $cur_max);
 
        // storing current maximum from
        // ith, in backward array
        $bw[$i] = $cur_max;
    }
 
    /* Initializing final ans by
        max_so_far so that, case
        when no element is removed
        to get max sum subarray is
        also handled */
    $fans = $max_so_far;
 
    // choosing maximum
    // ignoring ith element
    for ($i = 1; $i < $n - 1; $i++)
        $fans = max($fans, $fw[$i - 1] +
                           $bw[$i + 1]);
 
    return $fans;
}
 
// Driver Code
$arr = array(-2, -3, 4, -1,
             -2, 1, 5, -3);
$n = count($arr);
echo maxSumSubarrayRemovingOneEle($arr, $n);
 
// This code is contributed by anuj_67.
?>


Javascript


输出 :

9

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