Maximize array sum after K negations using Priority Queue
Last Updated :
24 Mar, 2023
Given an array of size n and a number k. We must modify array K number of times. Here modify array means in each operation we can replace any array element arr[i] by -arr[i]. We need to perform this operation in such a way that after K operations, sum of array must be maximum?
Examples:
Input : arr[] = {-2, 0, 5, -1, 2}
K = 4
Output: 10
// Replace (-2) by -(-2), array becomes {2, 0, 5, -1, 2}
// Replace (-1) by -(-1), array becomes {2, 0, 5, 1, 2}
// Replace (0) by -(0), array becomes {2, 0, 5, 1, 2}
// Replace (0) by -(0), array becomes {2, 0, 5, 1, 2}
Input : arr[] = {9, 8, 8, 5}
K = 3
Output: 20
We have discussed a O(nk) solution in below post.
Maximize array sum after K negations | Set 1
The idea used in above post is to replace the minimum element arr[i] in array by -arr[i] for current operation. In this way we can make sum of array maximum after K operations. Once interesting case is, once minimum element becomes 0, we don’t need to make any more changes.
The implementation used in above solution uses linear search to find minimum element. The time complexity of the above discussed solution is O(nk)
In this post an optimized solution is implemented that uses a priority queue (or binary heap) to find minimum element quickly.
Below is the implementation of the idea. It uses PriorityQueue class in Java.
C++
#include <bits/stdc++.h>
using namespace std;
int MaxSum( int a[], int n, int k)
{
int sum = 0;
priority_queue< int , vector< int >, greater< int >> pq;
for ( int i = 0; i < n; i++)
{
pq.push(a[i]);
}
while (k--)
{
int temp = pq.top();
pq.pop();
temp = (temp) * -1;
pq.push(temp);
}
while (!pq.empty())
{
sum = sum + pq.top();
pq.pop();
}
return sum;
}
int main()
{
int a[] = { -2, 0, 5, -1, 2 };
int n = sizeof (a) / sizeof (a[0]);
int k = 4;
cout << MaxSum(a, n, k);
return 0;
}
|
Java
import java.util.*;
class maximizeSum
{
public static int maxSum( int [] a, int k)
{
PriorityQueue<Integer> pq = new PriorityQueue<>();
for ( int x : a)
pq.add(x);
while (k-- > 0 )
{
int temp = pq.poll();
temp *= - 1 ;
pq.add(temp);
}
int sum = 0 ;
for ( int x : pq)
sum += x;
return sum;
}
public static void main (String[] args)
{
int [] arr = {- 2 , 0 , 5 , - 1 , 2 };
int k = 4 ;
System.out.println(maxSum(arr, k));
}
}
|
Python3
import heapq
def MaxSum(a, n, k):
sum = 0
pq = []
for i in range (n):
heapq.heappush(pq, a[i])
while k > 0 :
temp = heapq.heappop(pq)
temp = (temp) * - 1
heapq.heappush(pq, temp)
k - = 1
while (pq):
sum + = heapq.heappop(pq)
return sum
a = [ - 2 , 0 , 5 , - 1 , 2 ]
n = len (a)
k = 4
print (MaxSum(a, n, k))
|
C#
using System;
using System.Collections.Generic;
public class GFG {
public static int maxSum( int [] a, int k)
{
List< int > pq = new List< int >(a);
while (k-- > 0) {
pq.Sort();
int temp = pq[0];
pq.Remove(pq[0]);
temp *= -1;
pq.Add(temp);
}
int sum = 0;
foreach ( int x in pq) sum += x;
return sum;
}
static public void Main()
{
int [] arr = { -2, 0, 5, -1, 2 };
int k = 4;
Console.WriteLine(maxSum(arr, k));
}
}
|
Javascript
function maxSum(a, k)
{
let pq = [];
for (let i=0;i<a.length;i++)
pq.push(a[i]);
pq.sort();
while (k-- > 0)
{
let temp = pq.shift();
temp *= -1;
pq.push(temp);
pq.sort();
}
let sum = 0;
for (let i=0;i<pq.length;i++)
sum += pq[i];
return sum;
}
let arr = [-2, 0, 5, -1, 2];
let k = 4;
console.log(maxSum(arr, k));
|
Output:
10
Time Complexity: O(N log N), where N is the size of array A[].
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...