Open In App

Maximize array sum after K negations using Priority Queue

Last Updated : 13 Apr, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given an array of size n and an integer k. We must modify array k number of times. In each modification, we can replace any array element arr[i] by -arr[i]. The task is to perform this operation in such a way that after k operations, the sum of the array is maximum.

Examples : 

Input : arr[] = [-2, 0, 5, -1, 2], k = 4
Output: 10
Explanation:
1. Replace (-2) by -(-2), array becomes [2, 0, 5, -1, 2]
2. Replace (-1) by -(-1), array becomes [2, 0, 5, 1, 2]
3. Replace (0) by -(0), array becomes [2, 0, 5, 1, 2]
4. Replace (0) by -(0), array becomes [2, 0, 5, 1, 2]

Input : arr[] = [9, 8, 8, 5], k = 3
Output: 20
Explanation: Negate 5 three times. Array will become [9, 8, 8, -5].

Refer to Maximize array sum after K negations using Sorting for other approaches.

Approach:

The idea is to use min-heap to efficiently identify and modify the smallest element in each of the k operations, ensuring that we always negate the minimum value present in the array at any given step, which guarantees maximum possible sum after all operations.

Step by step approach:

  1. Create a min-heap and insert all array elements into it.
  2. Perform k operations by repeatedly extracting the minimum element.
  3. Negate the minimum element and reinsert it back into the heap.
  4. After k operations, calculate the sum of all elements in the heap.
C++
// C++ program to maximize array sum after K negations
#include <bits/stdc++.h>
using namespace std;

int maximizeSum(vector<int> &arr, int k) {
    int n = arr.size();
    
    priority_queue<int, vector<int>, greater<int>> pq;
    
    // Insert arrary elements into 
    // min heap.
    for (int i=0; i<n; i++) {
        pq.push(arr[i]);
    }
    
    // For k times, pop the minimum
    // element from heap, and apply
    // negation operation
    for (int i=0; i<k; i++) {
        int top = pq.top();
        pq.pop();
        
        pq.push(-1*top);
    }
    
    int sum = 0;
    while (!pq.empty()) {
        sum += pq.top();
        pq.pop();
    }
    
    return sum;
}

int main() {
    vector<int> arr = {-2, 0, 5, -1, 2};
    int k = 4;
    cout << maximizeSum(arr, k);
    return 0;
}
Java
// Java program to maximize array sum after K negations
import java.util.PriorityQueue;

class GfG {
    
    static int maximizeSum(int[] arr, int k) {
        int n = arr.length;
        
        PriorityQueue<Integer> pq = new PriorityQueue<>();
        
        // Insert array elements into 
        // min heap.
        for (int i = 0; i < n; i++) {
            pq.add(arr[i]);
        }
        
        // For k times, pop the minimum
        // element from heap, and apply
        // negation operation
        for (int i = 0; i < k; i++) {
            int top = pq.poll();
            pq.add(-1 * top);
        }
        
        int sum = 0;
        while (!pq.isEmpty()) {
            sum += pq.poll();
        }
        
        return sum;
    }
    
    public static void main(String[] args) {
        int[] arr = {-2, 0, 5, -1, 2};
        int k = 4;
        System.out.println(maximizeSum(arr, k));
    }
}
Python
# Python program to maximize array sum after K negations
import heapq

def maximizeSum(arr, k):
    n = len(arr)
    
    # Convert array into min heap
    heapq.heapify(arr)
    
    # For k times, pop the minimum
    # element from heap, and apply
    # negation operation
    for _ in range(k):
        top = heapq.heappop(arr)
        heapq.heappush(arr, -1 * top)
    
    return sum(arr)

if __name__ == "__main__":
    arr = [-2, 0, 5, -1, 2]
    k = 4
    print(maximizeSum(arr, k))
C#
// C# program to maximize array sum after K negations
using System;
using System.Collections.Generic;

class GfG {
    
    static int maximizeSum(int[] arr, int k) {
        int n = arr.Length;
        
        PriorityQueue<int> pq = new PriorityQueue<int>(new Comparer());
        
        // Insert array elements into 
        // min heap.
        for (int i = 0; i < n; i++) {
            pq.Enqueue(arr[i]);
        }
        
        // For k times, pop the minimum
        // element from heap, and apply
        // negation operation
        for (int i = 0; i < k; i++) {
            int top = pq.Dequeue();
            pq.Enqueue(-1 * top);
        }
        
        int sum = 0;
        while (pq.Count > 0) {
            sum += pq.Dequeue();
        }
        
        return sum;
    }
    
    static void Main() {
        int[] arr = { -2, 0, 5, -1, 2 };
        int k = 4;
        Console.WriteLine(maximizeSum(arr, k));
    }
}

// Custom comparator class for min heap
class Comparer : IComparer<int> {
    public int Compare(int a, int b) {
        if (a < b)
            return -1;
        else if (a > b)
            return 1;
        return 0;
    }
}

// Custom Priority queue 
class PriorityQueue<T> {
    private List<T> heap;
    private IComparer<T> comparer;

    public PriorityQueue(IComparer<T> comparer = null) {
        this.heap = new List<T>();
        this.comparer = comparer ?? Comparer<T>.Default;
    }

    public int Count => heap.Count;

    // Enqueue operation
    public void Enqueue(T item) {
        heap.Add(item);
        int i = heap.Count - 1;
        while (i > 0) {
            int parent = (i - 1) / 2;
            if (comparer.Compare(heap[parent], heap[i]) <= 0)
                break;
            Swap(parent, i);
            i = parent;
        }
    }

    // Dequeue operation
    public T Dequeue() {
        if (heap.Count == 0)
            throw new InvalidOperationException("Priority queue is empty.");
        T result = heap[0];
        int last = heap.Count - 1;
        heap[0] = heap[last];
        heap.RemoveAt(last);
        last--;
        int i = 0;
        while (true) {
            int left = 2 * i + 1;
            if (left > last)
                break;
            int right = left + 1;
            int minChild = left;
            if (right <= last && comparer.Compare(heap[right], heap[left]) < 0)
                minChild = right;
            if (comparer.Compare(heap[i], heap[minChild]) <= 0)
                break;
            Swap(i, minChild);
            i = minChild;
        }
        return result;
    }

    // Swap two elements in the heap
    private void Swap(int i, int j) {
        T temp = heap[i];
        heap[i] = heap[j];
        heap[j] = temp;
    }
}
JavaScript
// JavaScript program to maximize array sum after K negations

function maximizeSum(arr, k) {
    let pq = new PriorityQueue(Comparator);
    
    // Insert array elements into 
    // min heap.
    for (let i = 0; i < arr.length; i++) {
        pq.enqueue(arr[i]);
    }
    
    // For k times, pop the minimum
    // element from heap, and apply
    // negation operation
    for (let i = 0; i < k; i++) {
        let top = pq.dequeue();
        pq.enqueue(-1 * top);
    }
    
    let sum = 0;
    while (!pq.isEmpty()) {
        sum += pq.dequeue();
    }
    
    return sum;
}

// Comparator function to compare data
function Comparator(k1, k2) {
	if (k1 > k2) return -1;
	if (k1 < k2) return 1;
	return 0;
}

class PriorityQueue {
	constructor(compare) {
		this.heap = [];
		this.compare = compare;
	}

	enqueue(value) {
		this.heap.push(value);
		this.bubbleUp();
	}

	bubbleUp() {
		let index = this.heap.length - 1;
		while (index > 0) {
			let element = this.heap[index],
			    parentIndex = Math.floor((index - 1) / 2),
			    parent = this.heap[parentIndex];
			if (this.compare(element, parent) < 0) break;
			this.heap[index] = parent;
			this.heap[parentIndex] = element;
			index = parentIndex;
		}
	}

	dequeue() {
		let max = this.heap[0];
		let end = this.heap.pop();
		if (this.heap.length > 0) {
			this.heap[0] = end;
			this.sinkDown(0);
		}
		return max;
	}

	sinkDown(index) {
		let left = 2 * index + 1,
		    right = 2 * index + 2,
		    largest = index;

		if (
		    left < this.heap.length &&
		    this.compare(this.heap[left], this.heap[largest]) > 0
		) {
			largest = left;
		}

		if (
		    right < this.heap.length &&
		    this.compare(this.heap[right], this.heap[largest]) > 0
		) {
			largest = right;
		}

		if (largest !== index) {
			[this.heap[largest], this.heap[index]] = [
			            this.heap[index],
			            this.heap[largest],
			        ];
			this.sinkDown(largest);
		}
	}

	isEmpty() {
		return this.heap.length === 0;
	}
}


let arr = [-2, 0, 5, -1, 2];
let k = 4;
console.log(maximizeSum(arr, k));

Output
10


Next Article
Article Tags :
Practice Tags :

Similar Reads