给定一个数组,我们需要找到最大和子数组,也可以删除一个元素以获得最大和。
例子 :
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)