Given an array arr[], the task is to find the maximum sum subarray when removal of at most one element is allowed.
Examples:
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] sums up to 9, which is the maximum achievable sum.
Maximum sum subarray removing at most one element using prefix and suffix array:
Below is the idea to solve the problem:
If the element removal condition is not applied, this problem can be solved using Kadane’s algorithm but here one element can be removed also for increasing maximum sum. This condition can be handled using two arrays, prefix and suffix array. These arrays store the current maximum subarray sum from starting to ith index, and from ith index to ending respectively.
Follow the below steps to Implement the idea:
- Initialize two arrays, one for prefix max sum fw[] and another for suffix max sum bw[].
- Run two for loops
- First one to store the maximum current sum from prefix in fw[] and
- The other loop stores the same for suffix in bw[].
- Getting the current maximum and updating it is the same as Kadane’s algorithm.
- Now for one element removal iterate over each index i, calculate the maximum subarray sum after ignoring ith element i.e. fw[i-1] + bw[i+1]
- So loop for all possible index i and choose the maximum among them.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int maxSumSubarrayRemovingOneEle( int arr[], int n)
{
int fw[n], bw[n];
int cur_max = arr[0], max_so_far = arr[0];
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);
fw[i] = cur_max;
}
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);
bw[i] = cur_max;
}
int fans = max_so_far;
for ( int i = 1; i < n - 1; i++)
fans = max(fans,
max(0, fw[i - 1]) + max(0, bw[i + 1]));
if (fans == 0) {
return *max_element(arr, arr + n);
}
return fans;
}
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
import java.io.*;
class GFG {
static int maxSumSubarrayRemovingOneEle( int arr[],
int n)
{
int fw[] = new int [n];
int bw[] = new int [n];
int cur_max = arr[ 0 ], max_so_far = arr[ 0 ];
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);
fw[i] = cur_max;
}
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);
bw[i] = cur_max;
}
int fans = max_so_far;
for ( int i = 1 ; i < n - 1 ; i++)
fans = Math.max(fans, fw[i - 1 ] + bw[i + 1 ]);
return fans;
}
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));
}
}
|
Python3
def maxSumSubarrayRemovingOneEle(arr, n):
fw = [ 0 for k in range (n)]
bw = [ 0 for k in range (n)]
cur_max, max_so_far = arr[ 0 ], arr[ 0 ]
fw[ 0 ] = cur_max
for i in range ( 1 , n):
cur_max = max (arr[i], cur_max + arr[i])
max_so_far = max (max_so_far, cur_max)
fw[i] = cur_max
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)
bw[i] = cur_max
i - = 1
fans = max_so_far
for i in range ( 1 , n - 1 ):
fans = max (fans, fw[i - 1 ] + bw[i + 1 ])
return fans
if __name__ = = '__main__' :
arr = [ - 2 , - 3 , 4 , - 1 , - 2 , 1 , 5 , - 3 ]
N = len (arr)
print (maxSumSubarrayRemovingOneEle(arr, N))
|
C#
using System;
class GFG {
static int maxSumSubarrayRemovingOneEle( int [] arr,
int n)
{
int [] fw = new int [n];
int [] bw = new int [n];
int cur_max = arr[0], max_so_far = arr[0];
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);
fw[i] = cur_max;
}
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);
bw[i] = cur_max;
}
int fans = max_so_far;
for ( int i = 1; i < n - 1; i++)
fans = Math.Max(fans, fw[i - 1] + bw[i + 1]);
return fans;
}
public static void Main()
{
int [] arr = { -2, -3, 4, -1, -2, 1, 5, -3 };
int N = arr.Length;
Console.WriteLine(
maxSumSubarrayRemovingOneEle(arr, N));
}
}
|
Javascript
<script>
function maxSumSubarrayRemovingOneEle(arr, n)
{
let fw = [];
let bw = [];
let cur_max = arr[0], max_so_far = arr[0];
fw[0] = arr[0];
for (let 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);
fw[i] = cur_max;
}
cur_max = max_so_far = bw[n - 1] = arr[n - 1];
for (let 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);
bw[i] = cur_max;
}
let fans = max_so_far;
for (let i = 1; i < n - 1; i++)
fans = Math.max(fans, fw[i - 1] +
bw[i + 1]);
return fans;
}
let arr = [ -2, -3, 4, -1, -2, 1, 5, -3 ];
let n = arr.length;
document.write(
maxSumSubarrayRemovingOneEle(arr, n));
</script>
|
PHP
<?php
function maxSumSubarrayRemovingOneEle( $arr , $n )
{
$fw = array (); $bw = array ();
$cur_max = $arr [0];
$max_so_far = $arr [0];
$fw [0] = $arr [0];
for ( $i = 1; $i < $n ; $i ++)
{
$cur_max = max( $arr [ $i ],
$cur_max + $arr [ $i ]);
$max_so_far = max( $max_so_far ,
$cur_max );
$fw [ $i ] = $cur_max ;
}
$cur_max = $max_so_far =
$bw [ $n - 1] = $arr [ $n - 1];
for ( $i = $n - 2; $i >= 0; $i --)
{
$cur_max = max( $arr [ $i ],
$cur_max + $arr [ $i ]);
$max_so_far = max( $max_so_far ,
$cur_max );
$bw [ $i ] = $cur_max ;
}
$fans = $max_so_far ;
for ( $i = 1; $i < $n - 1; $i ++)
$fans = max( $fans , $fw [ $i - 1] +
$bw [ $i + 1]);
return $fans ;
}
$arr = array (-2, -3, 4, -1,
-2, 1, 5, -3);
$N = count ( $arr );
echo maxSumSubarrayRemovingOneEle( $arr , $N );
?>
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Efficient Approach using Constant Space and One-pass -:
Follow the below steps to Implement the idea :
curr represents current max sum including arr[i] -- either curr + arr[i] or arr[i] (if arr[i] > curr + arr[i], meaning dp is negative, we just drop curr and start over from arr[i] as there is no point to keep a negative sum)
prev represents current max sum excluding arr[i]
prev can be x + arr[i] since it already excluded one element previously. Or, it can be previous curr, meaning we exclude current element -- arr[i].
res keep track of the maximum sum seen so far
At each ith index check wether to include that index in sum or not.
For each element x in the array, calculate -:
curr = maximum(prev, x + curr)
prev = maximum(x, x + prev)
res = maximum(res, maximum(curr, prev))
return res; // maximum sum of array with one deletion
C++
#include <bits/stdc++.h>
using namespace std;
int maximumSum( int arr[], int n)
{
int res = INT_MIN, prev = 0, curr = 0;
for ( int i = 0; i < n; i++)
{
curr = max(prev, arr[i] + curr);
prev = max(arr[i], arr[i] + prev);
res = max(res, max(curr, prev));
}
return res;
}
int main()
{
int arr[] = { -2, -3, 4, -1, -2, 1, 5, -3 };
int n = sizeof (arr) / sizeof (arr[0]);
cout << maximumSum(arr, n);
return 0;
}
|
Java
import java.io.*;
class GFG {
public static int maximumSum( int [] arr) {
int res = Integer.MIN_VALUE, prev = 0 , curr = 0 ;
for ( int x : arr) {
curr = Math.max(prev, x + curr);
prev = Math.max(x, x + prev);
res = Math.max(res, Math.max(curr, prev));
}
return res;
}
public static void main(String arg[])
{
int arr[] = { - 2 , - 3 , 4 , - 1 , - 2 , 1 , 5 , - 3 };
System.out.print( maximumSum(arr));
}
}
|
Python3
import sys
def maximumSum(arr):
res = - sys.maxsize - 1
prev = 0
curr = 0
for x in arr:
curr = max (prev, x + curr)
prev = max (x, x + prev)
res = max (res, max (curr, prev))
return res
if __name__ = = '__main__' :
arr = [ - 2 , - 3 , 4 , - 1 , - 2 , 1 , 5 , - 3 ]
print (maximumSum(arr))
|
C#
using System;
class GFG{
public static int maximumSum( int [] arr){
int res = int .MinValue;
int prev = 0, curr = 0;
foreach ( int x in arr){
curr = Math.Max(prev, x + curr);
prev = Math.Max(x, x + prev);
res = Math.Max(res, Math.Max(curr, prev));
}
return res;
}
public static void Main( string [] args){
int [] arr = { -2, -3, 4, -1, -2, 1, 5, -3 };
Console.Write(maximumSum(arr));
}
}
|
Javascript
function maximumSum(arr) {
let res = -Infinity, prev = 0, curr = 0;
for (let i = 0; i < arr.length; i++) {
let x = arr[i];
curr = Math.max(prev, x + curr);
prev = Math.max(x, x + prev);
res = Math.max(res, Math.max(curr, prev));
}
return res;
}
const arr = [-2, -3, 4, -1, -2, 1, 5, -3];
console.log(maximumSum(arr));
|
Time Complexity : O(N)
Auxiliary Space : O(1)