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 strongly recommend that you click here and practice it, before moving on to the solution.
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.
// A PriorityQueue based C++ program to // maximize array sum after k negations. #include <bits/stdc++.h> using namespace std;
// Function to find Maximum sum // after K negations int MaxSum( int a[], int n, int k)
{ int sum = 0;
// Create a min heap for priority queue
priority_queue< int , vector< int >, greater< int >> pq;
// Insert all elements in f array in priority_queue
for ( int i = 0; i < n; i++)
{
pq.push(a[i]);
}
while (k--)
{
// Retrieve and remove min element
int temp = pq.top();
pq.pop();
// Modify the minimum element and
// add back to priority queue
temp = (temp) * -1;
pq.push(temp);
}
// Calculate the sum
while (!pq.empty())
{
sum = sum + pq.top();
pq.pop();
}
return sum;
} // Driver Code 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;
} // This code is contributed by Harshit Srivastava |
// A PriorityQueue based Java program to maximize array // sum after k negations. import java.util.*;
class maximizeSum
{ public static int maxSum( int [] a, int k)
{
// Create a priority queue and insert all array elements
// int
PriorityQueue<Integer> pq = new PriorityQueue<>();
for ( int x : a)
pq.add(x);
// Do k negations by removing a minimum element k times
while (k-- > 0 )
{
// Retrieve and remove min element
int temp = pq.poll();
// Modify the minimum element and add back
// to priority queue
temp *= - 1 ;
pq.add(temp);
}
// Compute sum of all elements in priority queue.
int sum = 0 ;
for ( int x : pq)
sum += x;
return sum;
}
// Driver code
public static void main (String[] args)
{
int [] arr = {- 2 , 0 , 5 , - 1 , 2 };
int k = 4 ;
System.out.println(maxSum(arr, k));
}
} |
# Python code # A PriorityQueue based Python program to # maximize array sum after k negations. # import library import heapq
# Function to find Maximum sum # after K negations def MaxSum(a, n, k):
sum = 0
# Create a min heap for priority queue
pq = []
# Insert all elements in f array in priority_queue
for i in range (n):
heapq.heappush(pq, a[i])
while k > 0 :
# Retrieve and remove min element
temp = heapq.heappop(pq)
# Modify the minimum element and
# add back to priority queue
temp = (temp) * - 1
heapq.heappush(pq, temp)
k - = 1
# Calculate the sum
while (pq):
sum + = heapq.heappop(pq)
return sum
# Driver Code a = [ - 2 , 0 , 5 , - 1 , 2 ]
n = len (a)
k = 4
print (MaxSum(a, n, k))
# This code is contributed by akashish__ |
// A PriorityQueue based C# program to maximize array // sum after k negations. using System;
using System.Collections.Generic;
public class GFG {
public static int maxSum( int [] a, int k)
{
// Create a priority queue and insert all array
// elements int
List< int > pq = new List< int >(a);
// Do k negations by removing a minimum element
// k times
while (k-- > 0) {
// Retrieve and remove min element
pq.Sort();
int temp = pq[0];
pq.Remove(pq[0]);
// Modify the minimum element and add back
// to priority queue
temp *= -1;
pq.Add(temp);
}
// Compute sum of all elements in priority queue.
int sum = 0;
foreach ( int x in pq) sum += x;
return sum;
}
// Driver code
static public void Main()
{
int [] arr = { -2, 0, 5, -1, 2 };
int k = 4;
Console.WriteLine(maxSum(arr, k));
}
} // contributed by akashish__ |
function maxSum(a, k)
{
let pq = [];
for (let i=0;i<a.length;i++)
pq.push(a[i]);
pq.sort();
// Do k negations by removing a minimum element k times
while (k-- > 0)
{
// Retrieve and remove min element
let temp = pq.shift();
// Modify the minimum element and add back
// to priority queue
temp *= -1;
pq.push(temp);
pq.sort();
}
// Compute sum of all elements in priority queue.
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));
// This code is contributed by aadityaburujwale. |
Output:
10
Time Complexity: O(N log N), where N is the size of array A[].
Auxiliary Space: O(N)