Maximum subarray sum by flipping signs of at most K array elements
Given an array arr[] of N integers and an integer K, The task is to find the maximum sub-array sum by flipping signs of at most K array elements.
Examples:
Input: arr[] = {-6, 2, -1, -1000, 2}, k = 2
Output: 1009
We can flip the signs of -6 and -1000, to get maximum subarray sum as 1009
Input: arr[] = {-1, -2, -100, -10}, k = 1
Output: 100
We can only flip the sign of -100 to get 100
Input: {1, 2, 100, 10}, k = 1
Output: 113
We do not need to flip any elements
Approach: The problem can be solved using Dynamic Programming. Let dp[i][j] be the maximum sub-array sum from index i with j flips. A recursive function can be written in order to solve the problem and we can use memoization to avoid multiple function calls. The recursive DP function (findSubarraySum(ind, flips)) will be called from every index with the number of initial flips as 0.
ans = max(0, a[ind] + findSubarraySum(ind + 1, flips, n, a, k))
ans = max(ans, -a[ind] + findSubarraySum(ind + 1, flips + 1, n, a, k))
If the value is negative, we are replacing it by 0, similarly as we do in Kadane’s algorithm.
The recursive function will have two states, one will be if we flip the i-th index. The second one is if we don’t flip the i-th index. The base cases are if the ind==n when we have completed a traversal till the last index. We can use memoization in order to store the results which can be used later to avoid multiple same-function calls. The maximum of all dp[i][0] will be our answer.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define right 2
#define left 4
int dp[left][right];
int findSubarraySum( int ind, int flips, int n, int a[],
int k)
{
if (flips > k)
return -1e9;
if (ind == n)
return 0;
if (dp[ind][flips] != -1)
return dp[ind][flips];
int ans = 0;
ans = max(
0,
a[ind] + findSubarraySum(ind + 1, flips, n, a, k));
ans = max(ans, -a[ind]
+ findSubarraySum(ind + 1, flips + 1,
n, a, k));
return dp[ind][flips] = ans;
}
int findMaxSubarraySum( int a[], int n, int k)
{
memset (dp, -1, sizeof (dp));
int ans = -1e9;
for ( int i = 0; i < n; i++)
ans = max(ans, findSubarraySum(i, 0, n, a, k));
if (ans == 0 && k == 0)
return *max_element(a, a + n);
return ans;
}
int main()
{
int a[] = { -1, -2, -100, -10 };
int n = sizeof (a) / sizeof (a[0]);
int k = 1;
cout << findMaxSubarraySum(a, n, k);
return 0;
}
|
Java
import java.util.Arrays;
class GFG {
static int right = 2 ;
static int left = 4 ;
static int [][] dp = new int [left][right];
static int findSubarraySum( int ind, int flips, int n,
int [] a, int k)
{
if (flips > k)
return ( int )(-1e9);
if (ind == n)
return 0 ;
if (dp[ind][flips] != - 1 )
return dp[ind][flips];
int ans = 0 ;
ans = Math.max( 0 , a[ind]
+ findSubarraySum(
ind + 1 , flips, n, a, k));
ans = Math.max(ans, -a[ind]
+ findSubarraySum(ind + 1 ,
flips + 1 ,
n, a, k));
return dp[ind][flips] = ans;
}
static int findMaxSubarraySum( int [] a, int n, int k)
{
for ( int i = 0 ; i < n; i++)
for ( int j = 0 ; j < k + 1 ; j++)
dp[i][j] = - 1 ;
int ans = ( int )(-1e9);
for ( int i = 0 ; i < n; i++)
ans = Math.max(ans,
findSubarraySum(i, 0 , n, a, k));
if (ans == 0 && k == 0 )
return Arrays.stream(a).max().getAsInt();
return ans;
}
public static void main(String[] args)
{
int [] a = { - 1 , - 2 , - 100 , - 10 };
int n = a.length;
int k = 1 ;
System.out.println(findMaxSubarraySum(a, n, k));
}
}
|
Python3
import numpy as np
right = 3 ;
left = 6 ;
dp = np.ones((left, right))
dp = - 1 * dp
def findSubarraySum(ind, flips, n, a, k) :
if (flips > k) :
return - 1e9 ;
if (ind = = n) :
return 0 ;
if (dp[ind][flips] ! = - 1 ) :
return dp[ind][flips];
ans = 0 ;
ans = max ( 0 , a[ind] +
findSubarraySum(ind + 1 ,
flips, n, a, k));
ans = max (ans, - a[ind] +
findSubarraySum(ind + 1 , flips + 1 ,
n, a, k));
dp[ind][flips] = ans;
return dp[ind][flips] ;
def findMaxSubarraySum(a, n, k) :
ans = - 1e9 ;
for i in range (n) :
ans = max (ans, findSubarraySum(i, 0 , n, a, k));
if ans = = 0 and k = = 0 :
return max (a);
return ans;
if __name__ = = "__main__" :
a = [ - 1 , - 2 , - 100 , - 10 ];
n = len (a) ;
k = 1 ;
print (findMaxSubarraySum(a, n, k));
|
C#
using System;
using System.Linq;
class GFG {
static int right = 2;
static int left = 4;
static int [, ] dp = new int [left + 1, right + 1];
static int findSubarraySum( int ind, int flips, int n,
int [] a, int k)
{
if (flips > k)
return -( int )1e9;
if (ind == n)
return 0;
if (dp[ind, flips] != -1)
return dp[ind, flips];
int ans = 0;
ans = Math.Max(0, a[ind]
+ findSubarraySum(
ind + 1, flips, n, a, k));
ans = Math.Max(ans, -a[ind]
+ findSubarraySum(ind + 1,
flips + 1,
n, a, k));
return dp[ind, flips] = ans;
}
static int findMaxSubarraySum( int [] a, int n, int k)
{
for ( int i = 0; i < n; i++)
for ( int j = 0; j < k + 1; j++)
dp[i, j] = -1;
int ans = -( int )1e9;
for ( int i = 0; i < n; i++)
ans = Math.Max(ans,
findSubarraySum(i, 0, n, a, k));
if (ans == 0 && k == 0)
return a.Max();
return ans;
}
static void Main()
{
int [] a = { -1, -2, -100, -10 };
int n = a.Length;
int k = 1;
Console.WriteLine(findMaxSubarraySum(a, n, k));
}
}
|
Javascript
<script>
let right = 2;
let left = 4;
let dp = new Array(left);
function findSubarraySum(ind, flips, n, a, k)
{
if (flips > k)
return (-1e9);
if (ind == n)
return 0;
if (dp[ind][flips] != -1)
return dp[ind][flips];
let ans = 0;
ans = Math.max(0, a[ind]
+ findSubarraySum(
ind + 1, flips, n, a, k));
ans = Math.max(ans, -a[ind]
+ findSubarraySum(ind + 1,
flips + 1,
n, a, k));
return dp[ind][flips] = ans;
}
function findMaxSubarraySum(a, n, k)
{
for (let i = 0; i < n; i++)
{
dp[i] = new Array(k);
for (let j = 0; j < k + 1; j++)
{
dp[i][j] = -1;
}
}
let ans = (-1e9);
for (let i = 0; i < n; i++)
ans = Math.max(ans,
findSubarraySum(i, 0, n, a, k));
if (ans == 0 && k == 0)
{
let max = Number.MIN_VALUE;
for (let i = 0; i < a.length; i++)
{
max = Math.max(max, a[i]);
}
return max;
}
return ans;
}
let a = [ -1, -2, -100, -10 ];
let n = a.length;
let k = 1;
document.write(findMaxSubarraySum(a, n, k));
</script>
|
Time Complexity: O(N * K), as we are using a loop to traverse N times and we are recursively calling the function K times which will cost O(K). Where N is the number of elements in the array and K is the limit of elements.
Auxiliary Space: O(N * K), as we are using extra space for memorization. Where N is the number of elements in the array and K is the limit of elements.
Last Updated :
16 Jun, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...