Minimum time to reduce all the elements to zero
Last Updated :
30 Nov, 2023
Given an array of positive integers arr[] of size N. Every second, all the positive values of the array decrease by 1 until they reach zero. Apart from this, we can also perform a special operation in one second to reduce any element by K. If reducing an element by K, makes it negative simply reduce it to zero. Find the minimum time to make all the elements of the array zero.
Examples:
Input: n = 1, k = 2, arr = {1}
Output: 1
Explanation: No operation needed.
Input: n = 1, k = 17, arr = {35}
Output: 3
Explanation: We will use operation three times in a row on the first element.
Approach: The problem can be solved using the following approach:
Use the Binary Search approach to search the minimum time to make all elements become 0. Suppose, we want to check whether we can reduce all the elements of the array to 0 in time T, then if y is the minimum number of times special operation is used on ith array element. Then (k*y) is the value reduced by special operation and T-y is the remaining time to make the ith element equal to 0 as time passes. So, we can calculate the minimum number of times special operation was performed on ith element,
- arr[i] <= k*y+(T-y)
- arr[i] <= k(y-1) + T
- arr[i] – T <= y(k-1)
- (arr[i] – T) / (k-1) <= y
So, minimum number of times a machine is used on wall X[i] is y = (X[i] – time) / (k – 1). Now, if the sum of the special operations needed for all the elements is less than T, then it is possible to reduce all the elements to 0 in time T, else it is impossible.
Steps to solve the problem:
- Calculate the range [l, r] in which our answer (minimum time) can lie.
- Maintain a function isPossible(T), which return where it is possible to make all the elements of the array 0 in time T,
- Declare cnt which keeps track of the total number of times special operations are needed to make all the elements in the array equal to 0.
- Now, for every element arr[i], calculate the number of special operations needed to make all the elements 0.
- Use ceil to ensure that partial operation count as full operation and add it to cnt.
- If the total number of special operations needed <= T, then return true, else return false.
- Keep reducing the search space [l, r], till we get our answer.
Below is the implementation of the efficient approach :
C++
#include <bits/stdc++.h>
using namespace std;
bool isPossible(vector< int >& arr, int k, int T)
{
int cnt = 0;
for ( int i = 0; i < arr.size(); i++) {
if (arr[i] - T > 0) {
cnt += ceil ((arr[i] - T) / ((k - 1) * 1.0));
}
}
return cnt <= T;
}
int solve(vector< int >& arr, int k)
{
if (k == 1) {
return *max_element(arr.begin(), arr.end());
}
int l = 0;
int r = *max_element(arr.begin(), arr.end());
int res = -1;
while (l <= r) {
int mid = (l + r) / 2;
if (isPossible(arr, k, mid) == true ) {
res = mid;
r = mid - 1;
}
else {
l = mid + 1;
}
}
return res;
}
int main()
{
vector< int > arr = { 35 };
int k = 17;
cout << solve(arr, k) << "\n" ;
return 0;
}
|
Java
import java.util.*;
class GFG {
public static boolean isPossible(List<Integer> arr,
int k, int T)
{
int cnt = 0 ;
for ( int i = 0 ; i < arr.size(); i++) {
if (arr.get(i) - T > 0 ) {
cnt += Math.ceil((arr.get(i) - T)
/ ( double )((k - 1 ) * 1.0 ));
}
}
return cnt <= T;
}
public static int solve(List<Integer> arr, int k)
{
if (k == 1 ) {
return Collections.max(arr);
}
int l = 0 ;
int r = Collections.max(arr);
int res = - 1 ;
while (l <= r) {
int mid = (l + r) / 2 ;
if (isPossible(arr, k, mid)) {
res = mid;
r = mid - 1 ;
}
else {
l = mid + 1 ;
}
}
return res;
}
public static void main(String[] args)
{
List<Integer> arr = Arrays.asList( 35 );
int k = 17 ;
System.out.println(solve(arr, k));
}
}
|
Python3
import math
def isPossible(arr, k, T):
cnt = 0
for i in range ( len (arr)):
if arr[i] - T > 0 :
cnt + = math.ceil((arr[i] - T) / (k - 1 ))
return cnt < = T
def solve(arr, k):
if k = = 1 :
return max (arr)
l = 0
r = max (arr)
res = - 1
while l < = r:
mid = (l + r) / / 2
if isPossible(arr, k, mid):
res = mid
r = mid - 1
else :
l = mid + 1
return res
arr = [ 35 ]
k = 17
print (solve(arr, k))
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GFG {
public static bool IsPossible(List< int > arr, int k,
int T)
{
int cnt = 0;
for ( int i = 0; i < arr.Count; i++) {
if (arr[i] - T > 0) {
cnt += ( int )Math.Ceiling(
(arr[i] - T) / ( double )((k - 1) * 1.0));
}
}
return cnt <= T;
}
public static int Solve(List< int > arr, int k)
{
if (k == 1) {
return arr.Max();
}
int l = 0;
int r = arr.Max();
int res = -1;
while (l <= r) {
int mid = (l + r) / 2;
if (IsPossible(arr, k, mid)) {
res = mid;
r = mid - 1;
}
else {
l = mid + 1;
}
}
return res;
}
public static void Main()
{
List< int > arr = new List< int >{ 35 };
int k = 17;
Console.WriteLine(Solve(arr, k));
}
}
|
Javascript
function isPossible(arr, k, T) {
let cnt = 0;
for (let i = 0; i < arr.length; i++) {
if (arr[i] - T > 0) {
cnt += Math.ceil((arr[i] - T) / (k - 1));
}
}
return cnt <= T;
}
function solve(arr, k) {
if (k === 1) {
return Math.max(...arr);
}
let l = 0;
let r = Math.max(...arr);
let res = -1;
while (l <= r) {
let mid = Math.floor((l + r) / 2);
if (isPossible(arr, k, mid)) {
res = mid;
r = mid - 1;
} else {
l = mid + 1;
}
}
return res;
}
const arr = [35];
const k = 17;
console.log(solve(arr, k));
|
Time complexity: O(N*log M), where N is the size of input array arr[] and M is the maximum element in arr[]
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...