25. Minimum Steps to Halve Sum
β GFG solution to the Minimum Steps to Halve Sum problem: find minimum operations to reduce array sum to half or less by repeatedly halving the largest element using greedy heap approach. π
The problem can be found at the following link: π Question Link
π§© Problem Description
You are given an array arr[] consisting of positive integers. Your task is to find the minimum number of operations required to make the sum of its elements less than or equal to half of the original sum. In one operation, you may replace any element with half of its value (with floating-point precision).
The goal is to minimize the number of operations needed to achieve this target sum by strategically choosing which elements to halve.
π Examples
Example 1
Input: arr[] = [8, 6, 2]
Output: 3
Explanation: Initial sum = (8 + 6 + 2) = 16, half = 8
Halve 8 β arr[] = [4, 6, 2], sum = 12 (still 12 > 8)
Halve 6 β arr[] = [4, 3, 2], sum = 9 (still 9 > 8)
Halve 4 β arr[] = [2, 3, 2], sum = 7 (now 7 < 8)
Hence, 3 operations are needed.Example 2
Input: arr[] = [9, 1, 2]
Output: 2
Explanation: Initial sum = 12, half = 6
Halve 9 β arr[] = [4.5, 1, 2], sum = 7.5 (still > 6)
Halve 4.5 β arr[] = [2.25, 1, 2], sum = 5.25 β€ 6
Hence, 2 operations are needed.π Constraints
$1 \le \text{arr.size()} \le 10^5$
$0 \le \text{arr}[i] \le 10^4$
β
My Approach
The optimal approach uses a Greedy Algorithm with a Max Heap (Priority Queue) to efficiently achieve the minimum operations:
Greedy Heap Strategy
Calculate Target:
Compute the total sum of all array elements.
Calculate target as half of the total sum.
Store the target value for comparison.
Build Max Heap:
Insert all array elements into a max heap (priority queue).
This allows efficient retrieval of the largest element in O(log n) time.
Greedy Selection:
Always select the largest element from the heap (greedy choice).
Halving the largest element gives maximum reduction in sum per operation.
This ensures minimum total operations needed.
Iterative Halving:
Extract the maximum element from heap.
Divide it by 2 and subtract half from current sum.
Push the halved value back into heap.
Increment operation counter.
Termination Condition:
Continue until current sum becomes less than or equal to target.
Return the total number of operations performed.
π Time and Auxiliary Space Complexity
Expected Time Complexity: O(n log n), where n is the size of the array. Building the heap takes O(n) time, and each of the k operations (where k can be up to n in worst case) involves heap extraction and insertion, each taking O(log n) time. The total complexity is dominated by O(k log n) which is O(n log n) in the worst case.
Expected Auxiliary Space Complexity: O(n), as we store all array elements in the priority queue (heap). The heap maintains at most n elements at any given time, requiring linear additional space.
π§βπ» Code (C++)
class Solution {
public:
int minOperations(vector<int>& arr) {
double s = accumulate(arr.begin(), arr.end(), 0.0), t = s / 2;
priority_queue<double> q(arr.begin(), arr.end());
int ops = 0;
while (s > t) {
double x = q.top(); q.pop();
s -= x / 2;
q.push(x / 2);
ops++;
}
return ops;
}
};β Code (Java)
class Solution {
public int minOperations(int[] arr) {
double s = 0, t;
PriorityQueue<Double> q = new PriorityQueue<>(Collections.reverseOrder());
for (int x : arr) {
s += x;
q.offer((double) x);
}
t = s / 2;
int ops = 0;
while (s > t) {
double x = q.poll();
s -= x / 2;
q.offer(x / 2);
ops++;
}
return ops;
}
}π Code (Python)
class Solution:
def minOperations(self, arr):
import heapq
s = sum(arr)
t = s / 2
h = [-x for x in arr]
heapq.heapify(h)
ops = 0
while s > t:
x = -heapq.heappop(h)
s -= x / 2
heapq.heappush(h, -x / 2)
ops += 1
return opsπ§ Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: π¬ Any Questions?. Let's make this learning journey more collaborative!
β If you find this helpful, please give this repository a star! β
πVisitor Count
Last updated