Maximum Subarray Sum after inverting at most two elements
Last Updated :
03 Jun, 2021
Given an array arr[] of integer elements, the task is to find maximum possible sub-array sum after changing the signs of at most two elements.
Examples:
Input: arr[] = {-5, 3, 2, 7, -8, 3, 7, -9, 10, 12, -6}
Output: 61
We can get 61 from index 0 to 10 by
changing the sign of elements at 4th and 7th indices i.e.
-8 and -9. We could have chosen -5 and -6 but this gives us
smaller sum 48.
Input: arr[] = {-5, -3, -18, 0, -4}
Output: 22
Approach: This problem can be solved using Dynamic Programming. Let's suppose there are n elements in the array. We build our solution from smallest length to largest length.
At each step, we change the solution for length i to i+1.
For each step we have three cases:
- (Maximum sub-array sum) by altering sign of at most 0 element.
- (Maximum sub-array sum) by altering sign of at most 1 element.
- (Maximum sub-array sum) by altering sign of at most 2 element.
These cases use each others previous values.
- Case 1: We have two choices either to take current element or to add current value into previous value of same case.we store whichever is larger.
- Case 2: We have two choices here
- We alter the sign of current element and then add it to 0 or previous case 1 value. we store whichever is larger.
- we take the current element of array and add it to previous case 2 value.If this value is larger than value we get in (a) case then we update else not.
- Case 3: We again have two choices here
- We alter the sign of current element and add it to previous case 2 value.
- We add current element into previous case 3 value. Larger value obtained from (a) and (b) is stored for current case.
We update the max value out of these 3 cases and store it in a variable.
For each case of each step we take Two dimensional array dp[n+1][3] if given array contains n elements.
Recurrence Relation:
Case 1: dp[i][0] = max(dp[i - 1][0] + arr[i], arr[i])
Case 2: dp[i][1] = max(max(0, dp[i - 1][0]) - arr[i], dp[i - 1][1] + arr[i])
Case 3: dp[i][2] = max(dp[i - 1][1] - arr[i], dp[i - 1][2] + arr[i])
solution = max(solution, max(dp[i][0], dp[i][1], dp[i][2]))
Below is the implementation of the above approach:
C++
// C++ implementation of the approach
#include <algorithm>
#include <iostream>
using namespace std;
// Function to return the maximum required sub-array sum
int maxSum(int a[], int n)
{
int ans = 0;
int* arr = new int[n + 1];
// Creating one based indexing
for (int i = 1; i <= n; i++)
arr[i] = a[i - 1];
// 2d array to contain solution for each step
int** dp = new int*[n + 1];
for (int i = 0; i <= n; i++)
dp[i] = new int[3];
for (int i = 1; i <= n; ++i) {
// Case 1: Choosing current or (current + previous)
// whichever is smaller
dp[i][0] = max(arr[i], dp[i - 1][0] + arr[i]);
// Case 2:(a) Altering sign and add to previous case 1 or
// value 0
dp[i][1] = max(0, dp[i - 1][0]) - arr[i];
// Case 2:(b) Adding current element with previous case 2
// and updating the maximum
if (i >= 2)
dp[i][1] = max(dp[i][1], dp[i - 1][1] + arr[i]);
// Case 3:(a) Altering sign and add to previous case 2
if (i >= 2)
dp[i][2] = dp[i - 1][1] - arr[i];
// Case 3:(b) Adding current element with previous case 3
if (i >= 3)
dp[i][2] = max(dp[i][2], dp[i - 1][2] + arr[i]);
// Updating the maximum value of variable ans
ans = max(ans, dp[i][0]);
ans = max(ans, dp[i][1]);
ans = max(ans, dp[i][2]);
}
// Return the final solution
return ans;
}
// Driver code
int main()
{
int arr[] = { -5, 3, 2, 7, -8, 3, 7, -9, 10, 12, -6 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << maxSum(arr, n);
return 0;
}
Java
// Java implementation of the approach
class GFG
{
// Function to return the maximum required sub-array sum
static int maxSum(int []a, int n)
{
int ans = 0;
int [] arr = new int[n + 1];
// Creating one based indexing
for (int i = 1; i <= n; i++)
arr[i] = a[i - 1];
// 2d array to contain solution for each step
int [][] dp = new int [n + 1][3];
for (int i = 1; i <= n; ++i)
{
// Case 1: Choosing current or (current + previous)
// whichever is smaller
dp[i][0] = Math.max(arr[i], dp[i - 1][0] + arr[i]);
// Case 2:(a) Altering sign and add to previous case 1 or
// value 0
dp[i][1] = Math.max(0, dp[i - 1][0]) - arr[i];
// Case 2:(b) Adding current element with previous case 2
// and updating the maximum
if (i >= 2)
dp[i][1] = Math.max(dp[i][1], dp[i - 1][1] + arr[i]);
// Case 3:(a) Altering sign and add to previous case 2
if (i >= 2)
dp[i][2] = dp[i - 1][1] - arr[i];
// Case 3:(b) Adding current element with previous case 3
if (i >= 3)
dp[i][2] = Math.max(dp[i][2], dp[i - 1][2] + arr[i]);
// Updating the maximum value of variable ans
ans = Math.max(ans, dp[i][0]);
ans = Math.max(ans, dp[i][1]);
ans = Math.max(ans, dp[i][2]);
}
// Return the final solution
return ans;
}
// Driver code
public static void main (String[] args)
{
int arr[] = { -5, 3, 2, 7, -8, 3, 7, -9, 10, 12, -6 };
int n = arr.length;
System.out.println(maxSum(arr, n));
}
}
// This code is contributed by ihritik
Python3
# Python3 implementation of the approach
# Function to return the maximum
# required sub-array sum
def maxSum(a, n):
ans = 0
arr = [0] * (n + 1)
# Creating one based indexing
for i in range(1, n + 1):
arr[i] = a[i - 1]
# 2d array to contain solution for each step
dp = [[0 for i in range(3)]
for j in range(n + 1)]
for i in range(0, n + 1):
# Case 1: Choosing current or
# (current + previous) whichever is smaller
dp[i][0] = max(arr[i], dp[i - 1][0] + arr[i])
# Case 2:(a) Altering sign and add to
# previous case 1 or value 0
dp[i][1] = max(0, dp[i - 1][0]) - arr[i]
# Case 2:(b) Adding current element with
# previous case 2 and updating the maximum
if i >= 2:
dp[i][1] = max(dp[i][1],
dp[i - 1][1] + arr[i])
# Case 3:(a) Altering sign and
# add to previous case 2
if i >= 2:
dp[i][2] = dp[i - 1][1] - arr[i]
# Case 3:(b) Adding current element
# with previous case 3
if i >= 3:
dp[i][2] = max(dp[i][2],
dp[i - 1][2] + arr[i])
# Updating the maximum value
# of variable ans
ans = max(ans, dp[i][0])
ans = max(ans, dp[i][1])
ans = max(ans, dp[i][2])
# Return the final solution
return ans
# Driver code
if __name__ == "__main__":
arr = [-5, 3, 2, 7, -8, 3,
7, -9, 10, 12, -6]
n = len(arr)
print(maxSum(arr, n))
# This code is contributed by Rituraj Jain
C#
// C# implementation of the approach
using System;
class GFG
{
// Function to return the maximum required sub-array sum
static int maxSum(int [] a, int n)
{
int ans = 0;
int [] arr = new int[n + 1];
// Creating one based indexing
for (int i = 1; i <= n; i++)
arr[i] = a[i - 1];
// 2d array to contain solution for each step
int [, ] dp = new int [n + 1, 3];
for (int i = 1; i <= n; ++i)
{
// Case 1: Choosing current or (current + previous)
// whichever is smaller
dp[i, 0] = Math.Max(arr[i], dp[i - 1, 0] + arr[i]);
// Case 2:(a) Altering sign and add to previous case 1 or
// value 0
dp[i, 1] = Math.Max(0, dp[i - 1, 0]) - arr[i];
// Case 2:(b) Adding current element with previous case 2
// and updating the maximum
if (i >= 2)
dp[i, 1] = Math.Max(dp[i, 1], dp[i - 1, 1] + arr[i]);
// Case 3:(a) Altering sign and add to previous case 2
if (i >= 2)
dp[i, 2] = dp[i - 1, 1] - arr[i];
// Case 3:(b) Adding current element with previous case 3
if (i >= 3)
dp[i, 2] = Math.Max(dp[i, 2], dp[i - 1, 2] + arr[i]);
// Updating the maximum value of variable ans
ans = Math.Max(ans, dp[i, 0]);
ans = Math.Max(ans, dp[i, 1]);
ans = Math.Max(ans, dp[i, 2]);
}
// Return the final solution
return ans;
}
// Driver code
public static void Main ()
{
int [] arr = { -5, 3, 2, 7, -8, 3, 7, -9, 10, 12, -6 };
int n = arr.Length;
Console.WriteLine(maxSum(arr, n));
}
}
// This code is contributed by ihritik
PHP
<?php
// PHP implementation of the approach
// Function to return the maximum
// required sub-array sum
function maxSum($a, $n)
{
$ans = 0;
$arr = array();
// Creating one based indexing
for ($i = 1; $i <= $n; $i++)
$arr[$i] = $a[$i - 1];
// 2d array to contain solution
// for each step
$dp = array(array());
for ($i = 1; $i <= $n; ++$i)
{
// Case 1: Choosing current or (current +
// previous) whichever is smaller
$dp[$i][0] = max($arr[$i],
$dp[$i - 1][0] + $arr[$i]);
// Case 2:(a) Altering sign and add to
// previous case 1 or value 0
$dp[$i][1] = max(0, $dp[$i - 1][0]) - $arr[$i];
// Case 2:(b) Adding current element with
// previous case 2 and updating the maximum
if ($i >= 2)
$dp[$i][1] = max($dp[$i][1],
$dp[$i - 1][1] + $arr[$i]);
// Case 3:(a) Altering sign and
// add to previous case 2
if ($i >= 2)
$dp[$i][2] = $dp[$i - 1][1] - $arr[$i];
// Case 3:(b) Adding current element
// with previous case 3
if ($i >= 3)
$dp[$i][2] = max($dp[$i][2],
$dp[$i - 1][2] + $arr[$i]);
// Updating the maximum value of variable ans
$ans = max($ans, $dp[$i][0]);
$ans = max($ans, $dp[$i][1]);
$ans = max($ans, $dp[$i][2]);
}
// Return the final solution
return $ans;
}
// Driver code
$arr = array( -5, 3, 2, 7, -8, 3,
7, -9, 10, 12, -6 );
$n = count($arr) ;
echo maxSum($arr, $n);
// This code is contributed by Ryuga
?>
JavaScript
<script>
// JavaScript implementation of the approach
// Function to return the maximum required sub-array sum
function maxSum(a, n)
{
let ans = 0;
let arr = new Array(n + 1);
// Creating one based indexing
for (let i = 1; i <= n; i++)
arr[i] = a[i - 1];
// 2d array to contain solution for each step
let dp = new Array(n + 1);
for (let i = 0; i <= n; ++i)
{
dp[i] = new Array(3);
for (let j = 0; j < 3; ++j)
{
dp[i][j] = 0;
}
}
for (let i = 1; i <= n; ++i)
{
// Case 1: Choosing current or (current + previous)
// whichever is smaller
dp[i][0] = Math.max(arr[i], dp[i - 1][0] + arr[i]);
// Case 2:(a) Altering sign and add to previous case 1 or
// value 0
dp[i][1] = Math.max(0, dp[i - 1][0]) - arr[i];
// Case 2:(b) Adding current element with previous case 2
// and updating the maximum
if (i >= 2)
dp[i][1] = Math.max(dp[i][1], dp[i - 1][1] + arr[i]);
// Case 3:(a) Altering sign and add to previous case 2
if (i >= 2)
dp[i][2] = dp[i - 1][1] - arr[i];
// Case 3:(b) Adding current element with previous case 3
if (i >= 3)
dp[i][2] = Math.max(dp[i][2], dp[i - 1][2] + arr[i]);
// Updating the maximum value of variable ans
ans = Math.max(ans, dp[i][0]);
ans = Math.max(ans, dp[i][1]);
ans = Math.max(ans, dp[i][2]);
}
// Return the final solution
return ans;
}
let arr = [ -5, 3, 2, 7, -8, 3, 7, -9, 10, 12, -6 ];
let n = arr.length;
document.write(maxSum(arr, n));
</script>
Time Complexity : O(N)
Space Complexity : O(3*N+N) = O(N)
Similar Reads
Maximum sum subarray after altering the array Given an array arr[] of size N. The task is to find the maximum subarray sum possible after performing the given operation at most once. In a single operation, you can choose any index i and either the subarray arr[0...i] or the subarray arr[i...N-1] can be reversed. Examples: Input: arr[] = {3, 4,
15+ min read
Maximize the maximum subarray sum after removing atmost one element Given an array arr[] of N integers, the task is to find the maximum sum of a subarray with at most one deletion allowed. The size of subarray to be considered should be at least 1.Examples: Input: arr[] = {1, 2, 3, -2, 3} Output: 9 The maximum sub-array sum is given by the sub-array {2, 3, -2, 3} He
2 min read
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[]
9 min read
Maximize subarray sum by inverting sign of elements of any subarray at most twice Given an array A of size n, find the maximum subarray sum after applying the given operation at most two times. In one operation, choose any two indices i and j and invert sign of all the elements from index i to index j, i.e, all positive elements in the range i to j become negative and all negativ
10 min read
Subarray with largest sum after excluding its maximum element Given an array arr[], the task is to find the starting and ending indices of the subarray with the largest sum after excluding its maximum element.Examples: Input: arr[] = {5, -2, 10, -1, 4} Output: 1 5 Explanation: Subarray[1:5] = {5, -2, 10, -1, 4} Sum of subarray excluding maximum element = 5 + (
9 min read