Maximum subarray sum possible after removing at most K array elements
Last Updated :
11 Apr, 2023
Given an array arr[] of size N and an integer K, the task is to find the maximum subarray sum by removing at most K elements from the array.
Examples:
Input: arr[] = { -2, 1, 3, -2, 4, -7, 20 }, K = 1
Output: 26
Explanation:
Removing arr[5] from the array modifies arr[] to { -2, 1, 3, -2, 4, 20 }
Subarray with maximum sum is { 1, 3, -2, 4, 20 }.
Therefore, the required output is 26.
Input:arr[] = { -1, 1, -1, -1, 1, 1 }, K=2
Output: 3
Explanation:
Removing arr[2] and arr[3] from the array modifies arr[] to { – 1, 1, 1, 1}
Subarray with maximum sum is { 1, 1, 1 }.
Therefore, the required output is 3.
Approach: The problem can be solved using Dynamic Programming. The idea is to use the concept of Kadane’s algorithm. Follow the steps below to solve the problem:
- Traverse the array arr[] and for every array element following two operations needs to be performed:
- Remove the current array element from the subarray.
- Include the current array element in the subarray.
- Therefore, the recurrence relation to solve this problem is as follows:
mxSubSum(i, j) = max(max(0, arr[i] + mxSubSum(i – 1, j)), mxSubSum(i – 1, j – 1))
i: Stores index of array element
j: Maximum count of elements that can be removed from the subarray
mxSubSum(i, j): Return maximum subarray sum from the subarray { arr[i], arr[N – 1] } by removing K – j array elements.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define M 100
int mxSubSum( int i, int * arr,
int j, int dp[][M])
{
if (i == 0) {
return dp[i][j] = max(0, arr[i]);
}
if (dp[i][j] != -1) {
return dp[i][j];
}
int X = max(0, arr[i]
+ mxSubSum(i - 1, arr, j, dp));
if (j == 0) {
return dp[i][j] = X;
}
int Y = mxSubSum(i - 1, arr, j - 1, dp);
return dp[i][j] = max(X, Y);
}
int MaximumSubarraySum( int n, int * arr, int k)
{
int dp[M][M];
memset (dp, -1, sizeof (dp));
mxSubSum(n - 1, arr, k, dp);
int res = 0;
for ( int i = 0; i < n; i++) {
for ( int j = 0; j <= k; j++) {
res = max(res, dp[i][j]);
}
}
if (*max_element(arr, arr + n) < 0) {
res = *max_element(arr, arr + n);
}
return res;
}
int main()
{
int arr[] = { -2, 1, 3, -2, 4, -7, 20 };
int K = 1;
int N = sizeof (arr) / sizeof (arr[0]);
cout << MaximumSubarraySum(N, arr, K) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG{
static final int M = 100 ;
static int mxSubSum( int i, int []arr,
int j, int dp[][])
{
if (i == 0 ) {
return dp[i][j] = Math.max( 0 , arr[i]);
}
if (dp[i][j] != - 1 ) {
return dp[i][j];
}
int X = Math.max( 0 , arr[i]
+ mxSubSum(i - 1 , arr, j, dp));
if (j == 0 )
{
return dp[i][j] = X;
}
int Y = mxSubSum(i - 1 , arr, j - 1 , dp);
return dp[i][j] = Math.max(X, Y);
}
static int MaximumSubarraySum( int n, int []arr, int k)
{
int [][]dp = new int [M][M];
for ( int i = 0 ; i < M; i++)
for ( int j = 0 ; j < M; j++)
dp[i][j] = - 1 ;
mxSubSum(n - 1 , arr, k, dp);
int res = 0 ;
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j <= k; j++) {
res = Math.max(res, dp[i][j]);
}
}
if (Arrays.stream(arr).max().getAsInt() < 0 ) {
res = Arrays.stream(arr).max().getAsInt();
}
return res;
}
public static void main(String[] args)
{
int arr[] = { - 2 , 1 , 3 , - 2 , 4 , - 7 , 20 };
int K = 1 ;
int N = arr.length;
System.out.print(MaximumSubarraySum(N, arr, K) + "\n" );
}
}
|
Python3
M = 100
def mxSubSum(i, arr, j):
global dp
if (i = = 0 ):
dp[i][j] = max ( 0 , arr[i])
return dp[i][j]
if (dp[i][j] ! = - 1 ):
return dp[i][j]
X = max ( 0 , arr[i] + mxSubSum(i - 1 , arr, j))
if (j = = 0 ):
dp[i][j] = X
return X
Y = mxSubSum(i - 1 , arr, j - 1 )
dp[i][j] = max (X, Y)
return dp[i][j]
def MaximumSubarraySum(n, arr, k):
mxSubSum(n - 1 , arr, k)
res = 0
for i in range (n):
for j in range (k + 1 ):
res = max (res, dp[i][j])
if ( max (arr) < 0 ):
res = max (arr)
return res
if __name__ = = '__main__' :
dp = [[ - 1 for i in range ( 100 )] for i in range ( 100 )]
arr = [ - 2 , 1 , 3 , - 2 , 4 , - 7 , 20 ]
K = 1
N = len (arr)
print (MaximumSubarraySum(N, arr, K))
|
C#
using System;
using System.Collections;
class GFG{
static int M = 100;
static int mxSubSum( int i, int []arr,
int j, int [,]dp)
{
if (i == 0)
{
return dp[i, j] = Math.Max(0, arr[i]);
}
if (dp[i, j] != -1)
{
return dp[i, j];
}
int X = Math.Max(0, arr[i] +
mxSubSum(i - 1, arr, j, dp));
if (j == 0)
{
return dp[i, j] = X;
}
int Y = mxSubSum(i - 1, arr, j - 1, dp);
return dp[i, j] = Math.Max(X, Y);
}
static int MaximumSubarraySum( int n, int []arr, int k)
{
int [,]dp = new int [M, M];
for ( int i = 0; i < M; i++)
for ( int j = 0; j < M; j++)
dp[i, j] = -1;
mxSubSum(n - 1, arr, k, dp);
int res = 0;
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j <= k; j++)
{
res = Math.Max(res, dp[i, j]);
}
}
Array.Sort(arr);
if (arr[n - 1] < 0)
{
res = arr[n - 1];
}
return res;
}
public static void Main(String[] args)
{
int []arr = { -2, 1, 3, -2, 4, -7, 20 };
int K = 1;
int N = arr.Length;
Console.WriteLine(MaximumSubarraySum(N, arr, K));
}
}
|
Javascript
<script>
var M = 100;
function mxSubSum(i, arr, j, dp)
{
if (i == 0)
{
dp[i][j] = Math.max(0, arr[i]);
return dp[i][j];
}
if (dp[i][j] != -1)
{
return dp[i][j];
}
var X = Math.max(
0, arr[i] + mxSubSum(i - 1, arr, j, dp));
if (j == 0)
{
dp[i][j] = X;
return dp[i][j]
}
var Y = mxSubSum(i - 1, arr, j - 1, dp);
dp[i][j] = Math.max(X, Y);
return dp[i][j]
}
function MaximumSubarraySum(n, arr, k)
{
var dp = Array.from(Array(M), () => Array(M).fill(-1));
mxSubSum(n - 1, arr, k, dp);
var res = 0;
for ( var i = 0; i < n; i++)
{
for ( var j = 0; j <= k; j++)
{
res = Math.max(res, dp[i][j]);
}
}
if (arr.reduce((a, b) => Math.max(a, b)) < 0)
{
res = arr.reduce((a, b) => Math.max(a, b));
}
return res;
}
var arr = [ -2, 1, 3, -2, 4, -7, 20 ];
var K = 1;
var N = arr.length;
document.write( MaximumSubarraySum(N, arr, K));
</script>
|
Time Complexity: O(N * K)
Auxiliary Space: O(N * K)
Efficient approach : Using DP Tabulation method ( Iterative approach )
The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memorization(top-down) because memorization method needs extra stack space of recursion calls.
Steps to solve this problem :
- Create a vector to store the solution of the subproblems.
- Initialize the table with base cases
- Fill up the table iteratively
- Return the final solution
Implementation :
C++
#include <bits/stdc++.h>
using namespace std;
#define M 100
int MaximumSubarraySum( int n, int * arr, int k)
{
int dp[n][k + 1];
memset (dp, 0, sizeof (dp));
dp[0][0] = max(0, arr[0]);
for ( int i = 1; i < n; i++) {
for ( int j = 0; j <= k; j++) {
int X = max(0, arr[i] + dp[i - 1][j]);
int Y = (j > 0) ? dp[i - 1][j - 1] : 0;
dp[i][j] = max(X, Y);
}
}
int res = 0;
for ( int i = 0; i < n; i++) {
for ( int j = 0; j <= k; j++) {
res = max(res, dp[i][j]);
}
}
if (*max_element(arr, arr + n) < 0) {
res = *max_element(arr, arr + n);
}
return res;
}
int main()
{
int arr[] = { -2, 1, 3, -2, 4, -7, 20 };
int K = 1;
int N = sizeof (arr) / sizeof (arr[0]);
cout << MaximumSubarraySum(N, arr, K) << endl;
return 0;
}
|
Java
import java.util.Arrays;
class Main
{
static int maximumSubarraySum( int n, int [] arr, int k) {
int [][] dp = new int [n][k + 1 ];
for ( int i = 0 ; i < n; i++) {
Arrays.fill(dp[i], 0 );
}
dp[ 0 ][ 0 ] = Math.max( 0 , arr[ 0 ]);
for ( int i = 1 ; i < n; i++) {
for ( int j = 0 ; j <= k; j++) {
int X = Math.max( 0 , arr[i] + dp[i - 1 ][j]);
int Y = (j > 0 ) ? dp[i - 1 ][j - 1 ] : 0 ;
dp[i][j] = Math.max(X, Y);
}
}
int res = 0 ;
for ( int i = 0 ; i < n; i++) {
for ( int j = 0 ; j <= k; j++) {
res = Math.max(res, dp[i][j]);
}
}
if (Arrays.stream(arr).max().getAsInt() < 0 ) {
res = Arrays.stream(arr).max().getAsInt();
}
return res;
}
public static void main(String[] args) {
int [] arr = { - 2 , 1 , 3 , - 2 , 4 , - 7 , 20 };
int K = 1 ;
int N = arr.length;
System.out.println(maximumSubarraySum(N, arr, K));
}
}
|
Python
def MaximumSubarraySum(n, arr, k):
dp = [[ 0 for j in range (k + 1 )] for i in range (n)]
dp[ 0 ][ 0 ] = max ( 0 , arr[ 0 ])
for i in range ( 1 , n):
for j in range (k + 1 ):
X = max ( 0 , arr[i] + dp[i - 1 ][j])
Y = dp[i - 1 ][j - 1 ] if j > 0 else 0
dp[i][j] = max (X, Y)
res = 0
for i in range (n):
for j in range (k + 1 ):
res = max (res, dp[i][j])
if max (arr) < 0 :
res = max (arr)
return res
if __name__ = = '__main__' :
arr = [ - 2 , 1 , 3 , - 2 , 4 , - 7 , 20 ]
K = 1
N = len (arr)
print (MaximumSubarraySum(N, arr, K))
|
C#
using System;
using System.Linq;
class MainClass
{
static int maximumSubarraySum( int n, int [] arr, int k)
{
int [][] dp = new int [n][];
for ( int i = 0; i < n; i++)
{
dp[i] = new int [k + 1];
for ( int j = 0; j <= k; j++)
{
dp[i][j] = 0;
}
}
dp[0][0] = Math.Max(0, arr[0]);
for ( int i = 1; i < n; i++)
{
for ( int j = 0; j <= k; j++)
{
int X = Math.Max(0, arr[i] + dp[i - 1][j]);
int Y = (j > 0) ? dp[i - 1][j - 1] : 0;
dp[i][j] = Math.Max(X, Y);
}
}
int res = 0;
for ( int i = 0; i < n; i++)
{
for ( int j = 0; j <= k; j++)
{
res = Math.Max(res, dp[i][j]);
}
}
if (arr.Max() < 0)
{
res = arr.Max();
}
return res;
}
public static void Main()
{
int [] arr = { -2, 1, 3, -2, 4, -7, 20 };
int K = 1;
int N = arr.Length;
Console.WriteLine(maximumSubarraySum(N, arr, K));
}
}
|
Javascript
function MaximumSubarraySum(n, arr, k) {
let dp = new Array(n);
for (let i = 0; i < n; i++) {
dp[i] = new Array(k + 1).fill(0);
}
dp[0][0] = Math.max(0, arr[0]);
for (let i = 1; i < n; i++) {
for (let j = 0; j <= k; j++) {
let X = Math.max(0, arr[i] + dp[i - 1][j]);
let Y = (j > 0) ? dp[i - 1][j - 1] : 0;
dp[i][j] = Math.max(X, Y);
}
}
let res = 0;
for (let i = 0; i < n; i++) {
for (let j = 0; j <= k; j++) {
res = Math.max(res, dp[i][j]);
}
}
if (Math.max(...arr) < 0) {
res = Math.max(...arr);
}
return res;
}
let arr = [-2, 1, 3, -2, 4, -7, 20];
let K = 1;
let N = arr.length;
console.log(MaximumSubarraySum(N, arr, K));
|
Output:
26
Time Complexity: O(N * K)
Auxiliary Space: O(N * K)
Share your thoughts in the comments
Please Login to comment...