Maximize sum of an Array by flipping sign of all elements of a single subarray
Last Updated :
04 Jan, 2023
Given an array arr[] of N integers, the task is to find the maximum sum of the array that can be obtained by flipping signs of any subarray of the given array at most once.
Examples:
Input: arr[] = {-2, 3, -1, -4, -2}
Output: 8
Explanation:
Flipping the signs of subarray {-1, -4, -2} modifies the array to {-2, 3, 1, 4, 2}. Therefore, the sum of the array = -2 + 3 + 1 + 4 + 2 = 8, which is the maximum possible.
Input: arr[] = {1, 2, -10, 2, -20}
Output: 31
Explanation:
Flipping the signs of subarray {-10, 2, -20} modifies the array to {1, 2, 10, -2, 20}. Therefore, the sum of the array = 1 + 2 + 10 – 2 + 20 = 31, which is the maximum possible.
Naive Approach: The simplest approach is to calculate the total sum of the array and then generate all possible subarrays. Now, for each subarray {A[i], … A[j]}, subtract its sum, sum(A[i], …, A[j]), from the total sum and flip the signs of the subarray elements. After flipping the subarray, add the sum of the flipped subarray, i.e. (-1 * sum(A[i], …, A[j])), to the total sum. Below are the steps:
- Find the total sum of the original array (say total_sum) and store it.
- Now, for all possible subarrays find the maximum of total_sum – 2 * sum(i, j).
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int maxSumFlip( int a[], int n)
{
int total_sum = 0;
for ( int i = 0; i < n; i++)
total_sum += a[i];
int max_sum = INT_MIN;
for ( int i = 0; i < n; i++)
{
int sum = 0;
for ( int j = i; j < n; j++)
{
sum += a[j];
max_sum = max(max_sum, total_sum - 2 * sum);
}
}
return max(max_sum, total_sum);
}
int main()
{
int arr[] = { -2, 3, -1, -4, -2 };
int N = sizeof (arr) / sizeof ( int );
cout << maxSumFlip(arr, N);
}
|
Java
import java.io.*;
public class GFG
{
public static int maxSumFlip( int a[], int n)
{
int total_sum = 0 ;
for ( int i = 0 ; i < n; i++)
total_sum += a[i];
int max_sum = Integer.MIN_VALUE;
for ( int i = 0 ; i < n; i++)
{
int sum = 0 ;
for ( int j = i; j < n; j++)
{
sum += a[j];
max_sum = Math.max(max_sum,
total_sum - 2 * sum);
}
}
return Math.max(max_sum, total_sum);
}
public static void main(String args[])
{
int arr[] = { - 2 , 3 , - 1 , - 4 , - 2 };
int N = arr.length;
System.out.println(maxSumFlip(arr, N));
}
}
|
Python3
import sys
def maxSumFlip(a, n):
total_sum = 0
for i in range (n):
total_sum + = a[i]
max_sum = - sys.maxsize - 1
for i in range (n):
sum = 0
for j in range (i, n):
sum + = a[j]
max_sum = max (max_sum,
total_sum - 2 * sum )
return max (max_sum, total_sum)
arr = [ - 2 , 3 , - 1 , - 4 , - 2 ]
N = len (arr)
print (maxSumFlip(arr, N))
|
C#
using System;
class GFG {
public static int maxSumFlip( int [] a, int n)
{
int total_sum = 0;
for ( int i = 0; i < n; i++)
total_sum += a[i];
int max_sum = int .MinValue;
for ( int i = 0; i < n; i++)
{
int sum = 0;
for ( int j = i; j < n; j++)
{
sum += a[j];
max_sum = Math.Max(max_sum,
total_sum - 2 * sum);
}
}
return Math.Max(max_sum, total_sum);
}
public static void Main(String[] args)
{
int [] arr = { -2, 3, -1, -4, -2 };
int N = arr.Length;
Console.WriteLine(maxSumFlip(arr, N));
}
}
|
Javascript
<script>
function maxSumFlip(a, n)
{
let total_sum = 0;
for (let i = 0; i < n; i++)
total_sum += a[i];
let max_ending_here = -a[0] - a[0];
let curr_sum = -a[0] - a[0];
for (let i = 1; i < n; i++)
{
curr_sum = Math.max(curr_sum + (-a[i] - a[i]),
(-a[i] - a[i]));
max_ending_here
= Math.max(max_ending_here, curr_sum);
}
let max_sum = total_sum + max_ending_here;
max_sum = Math.max(max_sum, total_sum);
return max_sum;
}
let arr = [ -2, 3, -1, -4, -2 ];
let N = arr.length;
document.write(maxSumFlip(arr, N));
</script>
|
Time Complexity: O(N2)
Auxiliary Space: O(1)
Efficient Approach: From the above approach, it can be observed that, to obtain maximum array sum, (2 * subarray sum) needs to be maximized for all subarrays. This can be done by using Dynamic Programming. Below are the steps:
- Find the minimum sum subarray from l[] using Kadane’s Algorithm
- This maximizes the contribution of (2 * sum) over all subarrays.
- Add the maximum contribution to the total sum of the array.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int maxSumFlip( int a[], int n)
{
int total_sum = 0;
for ( int i = 0; i < n; i++)
total_sum += a[i];
int b=0,temp=2e9;
for ( int i = 0; i < n; i++)
{
b+=a[i];
if (temp>b)
temp=b;
if (b>0)
b=0;
}
return max(total_sum,total_sum-2*temp);
}
int main()
{
int arr[] = { -2, 3, -1, -4, -2 };
int N = sizeof (arr) / sizeof ( int );
cout << maxSumFlip(arr, N);
}
|
Java
import java.util.*;
import java.io.*;
class GFG{
static int maxSumFlip( int ar[], int n)
{
int total_sum = 0 ;
for ( int i = 0 ; i < n ; i++){
total_sum += ar[i];
}
int b = 0 ;
int a = 2000000000 ;
for ( int i = 0 ; i < n ; i++)
{
b += ar[i];
if (a > b){
a = b;
}
if (b > 0 ){
b = 0 ;
}
}
return Math.max(total_sum, total_sum - 2 *a);
}
public static void main(String args[])
{
int arr[] = new int []{ - 2 , 3 , - 1 , - 4 , - 2 };
int N = arr.length;
System.out.println(maxSumFlip(arr, N));
}
}
|
Python3
def maxsum(l,n):
total_sum = sum (l)
current_sum = 0
minimum_sum = 0
for i in l:
current_sum + = i
minimum_sum = min (minimum_sum,current_sum)
current_sum = min (current_sum, 0 )
return max (total_sum,total_sum - 2 * minimum_sum)
l = [ - 2 , 3 , - 1 , - 4 , - 2 ]
n = len (l)
print (maxsum(l,n))
|
C#
using System;
public class GFG
{
public static int maxSumFlip( int [] ar, int n)
{
var total_sum = 0;
for ( int i = 0; i < n; i++)
{
total_sum += ar[i];
}
var b = 0;
var a = 2000000000;
for ( int i = 0; i < n; i++)
{
b += ar[i];
if (a > b)
{
a = b;
}
if (b > 0)
{
b = 0;
}
}
return Math.Max(total_sum,total_sum - 2 * a);
}
public static void Main(String[] args)
{
int [] arr = new int []{-2, 3, -1, -4, -2};
var N = arr.Length;
Console.WriteLine(GFG.maxSumFlip(arr, N));
}
}
|
Javascript
<script>
function maxsum(l,n){
let total_sum = 0;
for (let i = 0; i < n; i++)
total_sum += l[i];
let current_sum=0
let minimum_sum=0
for (let i of l){
current_sum += i
minimum_sum = Math.min(minimum_sum,current_sum)
current_sum = Math.min(current_sum,0)
}
return Math.max(total_sum, total_sum-2*minimum_sum)
}
let l = [-2, 3, -1, -4, -2]
let n = l.length
document.write(maxsum(l,n))
</script>
|
Time Complexity: O(N)
Auxiliary Space: O(1)
Note: Can also be done by finding minimum subarray sum and print max(TotalSum, TotalSum-2*(minsubarraysum))
Share your thoughts in the comments
Please Login to comment...