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)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
11 Apr, 2023
Like Article
Save Article