Minimize the Maximum Number of Balls in a Bucket
Last Updated :
06 Feb, 2024
Given an array arr[] and a positive integer K, where arr[i] represent number of balls in the ith bucket. The task is to minimize the maximum number of balls in a bucket by performing operation at most K times. The operation is to take any bucket and divide it into two new buckets with a positive number of balls in it. For example, a bucket of 5 balls can be divided into two new buckets of 1 and 4 balls, or two new buckets of 3 and 2 balls.
Examples:
Input: arr = {9}, K = 2
Output: 3
Explanation: Divide the bucket with 9 balls into two buckets of sizes 6 and 3. {9} -> {6,3}. Divide the bucket with 6 balls into two buckets of sizes 3 and 3. {6,3} -> {3,3,3}. The bucket with the most number of balls has 3 balls, so your penalty is 3 and you should return 3.
Input: arr = {2,4,8,2}, K = 4
Output: 2
Approach:
The binary search efficiently identifies the minimum size for buckets by iteratively narrowing the search space between the minimum and maximum initial bucket sizes. The isPossible function checks if achieving a specified maximum bucket size is feasible within a given limit of operations. This approach optimally explores the solution space, resulting in the minimum possible maximum number of balls in a bucket that satisfies the conditions.
Steps to solve the problem:
- isPossible Function:
- For each number n in the array:
- Calculate how many times mid can fit into n.
- If n is divisible by mid, subtract 1 from the count.
- Sum up these counts to get the total required operations.
- Check if the total operations are less than or equal to the given limit K.
- Return true if it is possible, otherwise return false.
- minimumSize Function:
- Set the initial search range (start and end).
- Initialize result to the maximum element in the array.
- Use binary search to find the minimum size:
- Calculate the middle value mid.
- If it is possible to achieve this mid using isPossible:
- Update result and adjust the search range.
- If not possible, adjust the search range accordingly
Below is the implementation of the above approach:
C++
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
bool isPossible(vector< int >& arr, int K, int mid)
{
int requiredOps = 0;
for ( int n : arr) {
int x = n / mid;
if (n % mid == 0)
x--;
requiredOps += x;
}
return requiredOps <= K;
}
int minimumSize(vector< int >& arr, int K)
{
int start = 1,
end = *max_element(arr.begin(), arr.end());
int result = end;
while (start <= end) {
int mid = start + (end - start) / 2;
if (isPossible(arr, K, mid))
result = mid, end = mid - 1;
else
start = mid + 1;
}
return result;
}
int main()
{
vector< int > arr = { 2, 4, 8, 2 };
int K = 4;
int result = minimumSize(arr, K);
cout << result << endl;
return 0;
}
|
Java
import java.util.*;
public class GFG {
static boolean isPossible(List<Integer> arr, int K, int mid) {
int requiredOps = 0 ;
for ( int n : arr) {
int x = n / mid;
if (n % mid == 0 )
x--;
requiredOps += x;
}
return requiredOps <= K;
}
static int minimumSize(List<Integer> arr, int K) {
int start = 1 ;
int end = Collections.max(arr);
int result = end;
while (start <= end) {
int mid = start + (end - start) / 2 ;
if (isPossible(arr, K, mid)) {
result = mid;
end = mid - 1 ;
} else {
start = mid + 1 ;
}
}
return result;
}
public static void main(String[] args) {
List<Integer> arr = new ArrayList<>();
arr.add( 2 );
arr.add( 4 );
arr.add( 8 );
arr.add( 2 );
int K = 4 ;
int result = minimumSize(arr, K);
System.out.println(result);
}
}
|
Python3
def is_possible(arr, K, mid):
required_ops = 0
for n in arr:
x = n / / mid
if n % mid = = 0 :
x - = 1
required_ops + = x
return required_ops < = K
def minimum_size(arr, K):
start = 1
end = max (arr)
result = end
while start < = end:
mid = start + (end - start) / / 2
if is_possible(arr, K, mid):
result = mid
end = mid - 1
else :
start = mid + 1
return result
if __name__ = = "__main__" :
arr = [ 2 , 4 , 8 , 2 ]
K = 4
result = minimum_size(arr, K)
print (result)
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static bool IsPossible(List< int > arr, int K, int mid)
{
int requiredOps = 0;
foreach ( int n in arr)
{
int x = n / mid;
if (n % mid == 0)
x--;
requiredOps += x;
}
return requiredOps <= K;
}
static int MinimumSize(List< int > arr, int K)
{
int start = 1;
int end = arr.Max();
int result = end;
while (start <= end)
{
int mid = start + (end - start) / 2;
if (IsPossible(arr, K, mid))
{
result = mid;
end = mid - 1;
}
else
{
start = mid + 1;
}
}
return result;
}
static void Main( string [] args)
{
List< int > arr = new List< int > { 2, 4, 8, 2 };
int K = 4;
int result = MinimumSize(arr, K);
Console.WriteLine(result);
}
}
|
Javascript
const isPossible = (arr, K, mid) => {
return arr.reduce((requiredOps, n) => {
const x = Math.floor(n / mid) - (n % mid === 0 ? 1 : 0);
return requiredOps + x;
}, 0) <= K;
};
const minimumSize = (arr, K) => {
let start = 1;
let end = Math.max(...arr);
let result = end;
while (start <= end) {
const mid = start + Math.floor((end - start) / 2);
if (isPossible(arr, K, mid)) {
result = mid;
end = mid - 1;
} else {
start = mid + 1;
}
}
return result;
};
const arr = [2, 4, 8, 2];
const K = 4;
const result = minimumSize(arr, K);
console.log(result);
|
Time Complexity: O(NlogN)
Auxiliary Space: O(1)
Share your thoughts in the comments
Please Login to comment...