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++
// C++ code to implement the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to find minimum operations
int minimumOperations(int N, int X,
vector<int> nums)
{
// Initialize answer as zero
int ans = 0;
// Create Max-Heap using
// Priority-queue
priority_queue<int> pq;
// Put all nums in the priority queue
for (int i = 0; i < N; i++)
pq.push(nums[i]);
// Execute the operation on num with
// max value until nums are left
// and X is positive
while (!pq.empty() and X > 0) {
if (pq.top() == 0)
break;
// Increment the answer everytime
ans++;
// num with maximum value
int num = pq.top();
// Removing the num
pq.pop();
// Reduce X's value and num's
// value as per the operation
X -= num;
num /= 2;
// If the num's value is positive
// insert back in the
// priority queue
if (num > 0)
pq.push(num);
}
// If X's value is positive then it
// is impossible to make X
// non-positive
if (X > 0)
return -1;
// Otherwise return the number of
// operations performed
return ans;
}
// Drivers code
int main()
{
int N = 3;
vector<int> nums = { 3, 4, 12 };
int X = 25;
// Function call
cout << minimumOperations(N, X, nums);
return 0;
}
Java
// Java code to implement the above approach
import java.io.*;
import java.util.*;
class GFG
{
// Function to find minimum operations
public static int minimumOperations(int N, int X,
int nums[])
{
// Initialize answer as zero
int ans = 0;
// Create Max-Heap using
// Priority-queue
PriorityQueue<Integer> pq = new PriorityQueue<>(
Collections.reverseOrder());
// Put all nums in the priority queue
for (int i = 0; i < N; i++)
pq.add(nums[i]);
// Execute the operation on num with
// max value until nums are left
// and X is positive
while (!pq.isEmpty() && X > 0) {
if (pq.peek() == 0)
break;
// Increment the answer everytime
ans++;
// num with maximum value
int num = pq.peek();
// Removing the num
pq.poll();
// Reduce X's value and num's
// value as per the operation
X -= num;
num /= 2;
// If the num's value is positive
// insert back in the
// priority queue
if (num > 0)
pq.add(num);
}
// If X's value is positive then it
// is impossible to make X
// non-positive
if (X > 0)
return -1;
// Otherwise return the number of
// operations performed
return ans;
}
// Driver Code
public static void main(String[] args)
{
int N = 3;
int nums[] = { 3, 4, 12 };
int X = 25;
// Function call
System.out.print(minimumOperations(N, X, nums));
}
}
// This code is contributed by Rohit Pradhan
Python3
# Python code to implement the above approach
# importing heapq module for implementing max heap
import heapq as hq
# Function to find minimum operations
def minimumOperations(N, X, nums):
# Initialize answer as zero
ans = 0
# assigning nums to pq
pq = nums
# converting pq to max heap
# using heapq module
hq._heapify_max(pq)
# Execute the operation on num with
# max value until nums are left
# and X is positive
while (len(pq) > 0 and X > 0):
if pq[len(pq)-1] == 0:
break
# Increment the answer everytime
ans += 1
# num with maximum value
# first element of max heap
# contains maximum value
num = pq[0]
# deleting one maximum element
# from max heap
pq[0] = pq[-1]
pq.pop()
# again converting current pq
# to max heap in O(n) time
hq._heapify_max(pq)
# Reduce X's value and num's
# value as per the operation
X -= num
num //= 2
# If the num's value is positive
# insert back in the
# priority queue
if num > 0:
pq.append(num)
hq._heapify_max(pq)
# If X's value is positive then it
# is impossible to make X
# non-positive
if X > 0:
return -1
# Otherwise return the number of
# operations performed
return ans
# Drivers code
N = 3
nums = [3, 4, 12]
X = 25
# Function call
print(minimumOperations(N, X, nums))
C#
// C# code for the above approach
using System;
using System.Collections.Generic;
class GFG {
// Function to find minimum operations
public static int minimumOperations(int N, int X,
int[] nums)
{
// Initialize answer as zero
int ans = 0;
// Create Max-Heap using
// Priority-queue
List<int> pq = new List<int>();
// Put all nums in the priority queue
for (int i = 0; i < N; i++){
pq.Add(nums[i]);
pq.Sort();
pq.Reverse();
}
// Execute the operation on num with
// max value until nums are left
// and X is positive
while (pq.Count != 0 && X > 0) {
if (pq[0] == 0)
break;
// Increment the answer everytime
ans++;
// num with maximum value
int num = pq[0];
// Removing the num
pq.RemoveAt(0);
// Reduce X's value and num's
// value as per the operation
X -= num;
num /= 2;
// If the num's value is positive
// insert back in the
// priority queue
if (num > 0){
pq.Add(num);
pq.Sort();
pq.Reverse();
}
}
// If X's value is positive then it
// is impossible to make X
// non-positive
if (X > 0)
return -1;
// Otherwise return the number of
// operations performed
return ans;
}
// Driver Code
public static void Main()
{
int N = 3;
int[] nums = { 3, 4, 12 };
int X = 25;
// Function call
Console.WriteLine(minimumOperations(N, X, nums));
}
}
// This code is contributed by sanjoy_62.
JavaScript
<script>
// JavaScript code to implement the above approach
// Function to find minimum operations
function minimumOperations(N, X,nums){
// Initialize answer as zero
let ans = 0
// Create Max-Heap using
// Priority-queue
let pq = []
// Put all nums in the priority queue
for(let i=0;i<N;i++)
pq.push(nums[i])
pq.sort((a,b)=>a-b)
// Execute the operation on num with
// max value until nums are left
// && X is positive
while (pq.length>0 && X > 0){
if (pq[pq.length-1]== 0)
break
// Increment the answer everytime
ans += 1
// num with maximum value
let num = pq[pq.length-1]
// Removing the num
pq.pop()
// Reduce X's value && num's
// value as per the operation
X -= num
num = Math.floor(num/2)
// If the num's value is positive
// insert back in the
// priority queue
if (num > 0)
pq.push(num)
pq.sort()
}
// If X's value is positive then it
// is impossible to make X
// non-positive
if (X > 0)
return -1
// Otherwise return the number of
// operations performed
return ans
}
// Drivers code
let N = 3
let nums = [ 3, 4, 12 ]
let X = 25
// Function call
document.write(minimumOperations(N, X, nums))
// This code is contributed by shinjanpatra
<script>
Time Complexity: O(N * log N)
Auxiliary Space: O(N)
Similar Reads
Minimize operations to convert Array elements to 0s Given an array nums[] of length N containing non-negative integers, the task is to convert all elements from index 0 to N-2 to zero, after doing the below operations minimum number of times. In one operation select two indices i and j such that i < j and all the elements between i and j has to be
6 min read
Minimize decrements to make each Array elements same or 0 Given an array arr[] consisting of N positive integers. In one operation any number of the array can be decremented by 1. The task is to find the minimum number of operations required to make all of the elements equal or 0. Examples: Input: arr[] = {4, 1, 6, 6}Output: 5Explanation: Remove 1 from arr
5 min read
Minimize steps to make Array elements 0 by reducing same A[i] - X from Subarray Given an array A[] of size N, the task is to find the minimum number of operations required to make all the elements of the array zero. In one step, the following operations are done on a subarray of the given array: Any integer X is chosenIf an element is greater than X (A[i] > X), the array ele
6 min read
Minimize the sum of MEX by removing all elements of array Given an array of integers arr[] of size N. You can perform the following operation N times: Pick any index i, and remove arr[i] from the array and add MEX(arr[]) i.e., Minimum Excluded of the array arr[] to your total score. Your task is to minimize the total score. Examples: Input: N = 8, arr[] =
7 min read
Minimum sum after subtracting multiples of k from the elements of the array Given an integer K and an integer array, the task is to find the minimum possible sum of all the elements of the array after they are reduced by subtracting a multiple of K from each element (the result must be positive and every element of the array must be equal after this reduction). If the array
15 min read