Minimize subtraction of Array elements to make X at most 0
Last Updated :
02 Aug, 2022
Given a number X, and an array arr[] of length N containing the N numbers. The task is to find the minimum number of operations required to make X non-positive. In one operation:
- Select any one number Y from the array and reduce X by Y.
- Then make Y = Y/2 (take floor value if Y is odd).
- If it is not possible to make X non-positive, return -1.
Examples:
Input: N = 3, arr[] = {3, 4, 12}, X = 25
Output: 4
Explanation: Operation 1: Y=12, X reduces to 13, Y becomes 6, arr[]: {3, 4, 6}
Operation 2: Y = 6, X reduces to 7, Y becomes 3, arr[]: {3, 4, 3}
Operation 3: Y = 4, X reduces to 3, Y becomes 2, arr[]: {3, 2, 3}
Operation 4: Y = 3, X reduces to 0, Y becomes 1, arr[]: {1, 2, 3}
Total operations will be 4.
Input: N = 3, arr[] = {11, 11, 110}, X = 11011
Output: -1
Explanation: It is impossible to make X non-positive
Approach: This problem can be solved using max-heap (priority queue) based on the following idea:
To minimize subtraction, it is optimal to subtract the maximum value each time. For this reason use a max-heap so that the maximum value numbers remain on top and perform the operation using the topmost element and keep checking if the number becomes non-positive or not.
Follow the below illustration for a better understanding.
Illustration:
Consider arr[] = {3, 4, 12} and X = 25
So max heap (say P) = [3, 4, 12]
1st step:
=> Maximum element (Y) = 12.
=> Subtract 12 from 25. X = 25 – 12 = 13. Y = 12/2 = 6.
=> P = {3, 4, 6}.
2nd step:
=> Maximum element (Y) = 6.
=> Subtract 6 from 13. X = 13 – 6 = 7. Y = 6/2 = 3.
=> P = {3, 3, 4}.
3rd step:
=> Maximum element (Y) = 4.
=> Subtract 4 from 7. X = 7 – 4 = 3. Y = 4/2 = 2.
=> P = {2, 3, 3}.
4th step:
=> Maximum element (Y) = 3.
=> Subtract 3 from 3. X = 3 – 3 = 0. Y = 3/2 = 1.
=> P = {1, 2, 3}.
X is non-positive. So operations required = 4
Follow the steps to solve the problem:
- Create a max-heap (implemented by priority queue)and store all the numbers in it.
- Perform the following until the priority queue is not empty and the X is positive.
- Use the number having the maximum value. This will be the number on top of the priority queue.
- Remove the top number from the priority queue and perform the operation as stated in the problem.
- After performing the operation, if Y is positive add it back to the priority queue.
- Increment the answer by 1 every time.
- After the completion of the above process, if X is positive then it is impossible to make it non-positive and thus return -1.
- Otherwise, return the answer.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
int minimumOperations( int N, int X,
vector< int > nums)
{
int ans = 0;
priority_queue< int > pq;
for ( int i = 0; i < N; i++)
pq.push(nums[i]);
while (!pq.empty() and X > 0) {
if (pq.top() == 0)
break ;
ans++;
int num = pq.top();
pq.pop();
X -= num;
num /= 2;
if (num > 0)
pq.push(num);
}
if (X > 0)
return -1;
return ans;
}
int main()
{
int N = 3;
vector< int > nums = { 3, 4, 12 };
int X = 25;
cout << minimumOperations(N, X, nums);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG
{
public static int minimumOperations( int N, int X,
int nums[])
{
int ans = 0 ;
PriorityQueue<Integer> pq = new PriorityQueue<>(
Collections.reverseOrder());
for ( int i = 0 ; i < N; i++)
pq.add(nums[i]);
while (!pq.isEmpty() && X > 0 ) {
if (pq.peek() == 0 )
break ;
ans++;
int num = pq.peek();
pq.poll();
X -= num;
num /= 2 ;
if (num > 0 )
pq.add(num);
}
if (X > 0 )
return - 1 ;
return ans;
}
public static void main(String[] args)
{
int N = 3 ;
int nums[] = { 3 , 4 , 12 };
int X = 25 ;
System.out.print(minimumOperations(N, X, nums));
}
}
|
Python3
import heapq as hq
def minimumOperations(N, X, nums):
ans = 0
pq = nums
hq._heapify_max(pq)
while ( len (pq) > 0 and X > 0 ):
if pq[ len (pq) - 1 ] = = 0 :
break
ans + = 1
num = pq[ 0 ]
pq[ 0 ] = pq[ - 1 ]
pq.pop()
hq._heapify_max(pq)
X - = num
num / / = 2
if num > 0 :
pq.append(num)
hq._heapify_max(pq)
if X > 0 :
return - 1
return ans
N = 3
nums = [ 3 , 4 , 12 ]
X = 25
print (minimumOperations(N, X, nums))
|
C#
using System;
using System.Collections.Generic;
class GFG {
public static int minimumOperations( int N, int X,
int [] nums)
{
int ans = 0;
List< int > pq = new List< int >();
for ( int i = 0; i < N; i++){
pq.Add(nums[i]);
pq.Sort();
pq.Reverse();
}
while (pq.Count != 0 && X > 0) {
if (pq[0] == 0)
break ;
ans++;
int num = pq[0];
pq.RemoveAt(0);
X -= num;
num /= 2;
if (num > 0){
pq.Add(num);
pq.Sort();
pq.Reverse();
}
}
if (X > 0)
return -1;
return ans;
}
public static void Main()
{
int N = 3;
int [] nums = { 3, 4, 12 };
int X = 25;
Console.WriteLine(minimumOperations(N, X, nums));
}
}
|
Javascript
<script>
function minimumOperations(N, X,nums){
let ans = 0
let pq = []
for (let i=0;i<N;i++)
pq.push(nums[i])
pq.sort((a,b)=>a-b)
while (pq.length>0 && X > 0){
if (pq[pq.length-1]== 0)
break
ans += 1
let num = pq[pq.length-1]
pq.pop()
X -= num
num = Math.floor(num/2)
if (num > 0)
pq.push(num)
pq.sort()
}
if (X > 0)
return -1
return ans
}
let N = 3
let nums = [ 3, 4, 12 ]
let X = 25
document.write(minimumOperations(N, X, nums))
<script>
|
Time Complexity: O(N * log N)
Auxiliary Space: O(N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...