Skip to main content

Binary Search

Maximum Candies Allocated to K Children Solution

Maximum Candies Allocated to K Children Problem Description:

You are given a 0-indexed integer array candies. Each element in the array denotes a pile of candies of size candies[i]. You can divide each pile into any number of sub-piles, but you cannot merge two piles together.
You are also given an integer k. You should allocate piles of candies to k children such that each child gets the same number of candies. Each child can take at most one pile of candies, and some piles of candies may go unused.
Return the maximum number of candies each child can get.
maximum-candies-allocated-to-k-children-Problem Description

Examples:

Input: candies = [5,8,6], k = 3
Output
: 5
Explanation
: We can divide candies[1] into 2 piles of size 5 and 3, and candies[2] into 2 piles of size 5 and 1. We now have five piles of candies of sizes 5, 5, 3, 5, and 1.
We can allocate the 3 piles of size 5 to 3 children.
It can be proven that each child cannot receive more than 5 candies.

Input: candies = [2,5], k = 11
Output
: 0
Explanation
: There are 11 children but only 7 candies in total, so it is impossible to ensure each child receives at least one candy.
Thus, each child gets no candy, and the answer is 0.

Constraints:

1 <= candies.length <= 10⁵
1 <= candies[i] <= 10⁷
1 <= k <= 10¹²

Brute Force Approach

To approach the problem, we are given an integer array candies and an integer k, and we need to determine the maximum number of candies each child can get while ensuring that every child receives the same number of candies. Each child can take at most one pile, and we can split piles but cannot merge them.

Our goal is to find the maximum number of candies each child can receive. If it is impossible to allocate candies to all k children, we return 0.

What can be the minimum number of candies each child can get?

The minimum number of candies required should be 0, because if we try to distribute candies but the total number of available candies is less than k, then no child can receive any candies, and the answer must be 0.

Now that we know the minimum number of candies, what would be the maximum number of candies each child can get?

The maximum number of candies required should be max(candies). This is because, in the best case, if k is small enough, one child could receive an entire pile of candies without needing to split it.

Thus, our search space for the answer ranges from 0 to max(candies). Now, the problem reduces to finding the maximum number of candies that can be given to each child while ensuring that k children receive candies.

A basic approach is to iterate through all possible values from 0 to max(candies) and check whether it is possible to allocate candies such that k children receive at least one pile each.

  • If it is possible, then it is a valid solution.
  • Otherwise, we decrease the number of candies per child and check again.
  • We continue this process until we find the maximum number of candies that allows us to distribute piles to k children.

We can either start from 0 and go up to max(candies) or start from max(candies) and go down to 0. The idea is to start from 0 to max(candies) and stop whenever we find the point where it's not possible to give k children the candies they need, and return the point before it as it was the maximum number of candies we can give to k children.

Consider candies = [5,8,6] and k = 3.
We start by setting the smallest possible value as 0 and the largest possible value as 8 (since max(candies) = 8).

We then check how many children can receive piles for different values of candies per child:

  • If each child gets 0 candies, we can make infinitely many piles, so it works.
  • Similarly, if each child gets 1, 2, or 3 candies, we can make enough piles to distribute to k children, so it will also work.
  • If each child gets 4 candies, we can make more than 3 piles, so it works.
  • If each child gets 5 candies, we can make exactly 3 piles, so it works.
  • If each child gets 6 candies, we can only make 2 piles, which is less than k = 3, so this does not work.

Since 6 is the first point where it's not possible to give k children the candies they need, we return 5, the point before it.

Thus, the answer is 5.

We can see that every number from 0 to 5 allows us to distribute candies to k children. But as soon as we try 6 or more, it’s no longer possible because we don’t have enough candies to give each child at least that much.

Let's call the maximum number of candies each child can receive as maxcandies.
Any number of candies from maxcandies+1 to max(candies) won't work because it will always result in fewer than k piles.
However, any number of candies from 0 to maxcandies will allow us to form at least k piles.

Therefore, maxcandies is the largest number of candies each child can receive while ensuring k children get a pile, and we return maxcandies as the answer. Any number from 0 to maxcandies will work because we can still distribute the candies, but as soon as we try maxcandies + 1 or more, it won’t be possible anymore.

maximum-candies-allocated-to-k-children

Explaining the Candy Distribution Process in Real-World Terms

Imagine you have piles of candies and a group of k children waiting eagerly for their share. Your task is to figure out how many candies each child can receive, ensuring that each child gets at least x candies (let x be any number of candies we want to distribute per child). The challenge is to maximize this number x while still distributing candies to at least k children.

Step 1: Setting Up the Process

To start, you need to determine if it’s possible to distribute the candies fairly for a given x.
Think of x as the minimum number of candies you want each child to receive.
If x is too high, some children will be left without any candies. If x is too low, you might not be maximizing the distribution.

Step 2: Counting the Number of Piles

To see if distributing x candies per child is possible, you need to count how many children can receive at least x candies.
You do this by going through each pile of candies you have:

  • For each pile, ask yourself: How many children can I serve with this pile if each child gets x candies?
  • This is calculated as candies[i] // x, meaning you are dividing the total candies in that pile by x to see how many full piles you can create.
  • For example, if you have 10 candies in a pile and x = 3, then 10 // 3 = 3 full piles. This means you can give 3 children exactly 3 candies each from that one pile.
  • By doing this for every pile, you are effectively breaking down large piles into smaller, manageable portions that can be distributed to individual children.

Step 3: Keeping Track of Distribution

To keep track of how many children you can serve, you use a counter called pileCount.

  • Every time you determine how many children a pile can serve (using candies[i] // x), you add that number to pileCount.
  • This is similar to keeping a tally of how many children are receiving candies as you go through each pile.

Step 4: Checking if the Goal is Met

Once you’ve counted all the piles:

  • You check if pileCount is greater than or equal to k.
  • If it is, then x is a valid number of candies to give each child because you can serve at least k children.
  • If it’s not, then x is too high, and not enough children are getting candies.

Why This Works in the Real World

  • Dividing the candies by x helps you figure out how to split large piles into smaller portions that can be shared.
  • Keeping track with pileCount ensures you don’t leave any child out.
  • This method guarantees that you are fairly maximizing the candy distribution while meeting the minimum requirement of serving k children.

Ultimately, this process helps you strike a balance between giving as many candies as possible to each child and ensuring that no child is left without.

Let's understand with an example:

Maximum Candies Allocated to K Children example:

candies = [1, 2, 3, 4, 10], k = 5
Start from i = 0 (minimum candies per child).
Go up to i = max(candies) = 10 (we’ll check all possible values of candies per child).

Check for Each i from 0 to 10

i = 0:
Total piles = 1/0 + 2/0 + 3/0 + 4/0 + 10/0 → Infinite piles (always possible). Valid.

i = 1:
Total piles = 1/1 + 2/1 + 3/1 + 4/1 + 10/1 = 1 + 2 + 3 + 4 + 10 = 20.
Since 20 ≥ 5, valid.

i = 2:
Total piles = 1/2 + 2/2 + 3/2 + 4/2 + 10/2 = 0 + 1 + 1 + 2 + 5 = 9.
Since 9 ≥ 5, valid.

i = 3:
Total piles = 1/3 + 2/3 + 3/3 + 4/3 + 10/3 = 0 + 0 + 1 + 1 + 3 = 5.
Since 5 = 5, valid.

i = 4:
Total piles = 1/4 + 2/4 + 3/4 + 4/4 + 10/4 = 0 + 0 + 0 + 1 + 2 = 3.
Since 3 < 5, invalid.

Since i = 3 was the last valid case before an invalid one, the maximum candies each child can get is 3.
Output: 3.

Steps to Implement the Solution:

Define the Helper Function (isPossible):
Initialize pileCount: Track the total number of piles that can be formed.
Iterate through candies array:
For each candy pile, if the pile has at least m candies, calculate how many piles can be made from that candy pile by dividing it by m.
Add the result to pileCount.
Return whether pileCount >= k: If the total piles made is greater than or equal to k, return true, otherwise false.

Find the Range for the Number of Candies per Child:
Initialize search range:
Set l = 0 (minimum possible candies per child).
Set r = max(candies) (maximum candies per child).

Iterate Over All Possible Candies per Child:
Iterate from l to r:
For each value of i from l to r, check if it's possible to form k piles with at least i candies per pile using the isPossible function.
If an invalid i is found, return the last valid i, as it represents the maximum number of candies each child can get.

If no valid i is found after iterating, return 0, indicating that it's not possible to allocate candies in such a way that each child gets at least i candies.

Find the Maximum Candies Allocated to K Children LeetCode solution below.

Maximum Candies Allocated to K Children solution / Code Implementation
1. Maximum Candies Allocated to K Children solution in c++ Try on Compiler
#include <vector>
#include <algorithm>
using namespace std;

class Solution {
    // Function to check if it's possible to make 'k' piles where each pile has at least 'm' candies
    bool isPossible(vector<int> &candies, long long k, int m) {

        // If 'm' is 0, it's always possible as we can create an infinite number of piles
        if (m == 0) return true;

        long long pileCount = 0;

        // Loop through each candy pile
        for (int i = 0; i < candies.size(); i++) {
            
            // Count the number of piles we can form by dividing the candies in this pile by 'm'
            pileCount += (candies[i] / m);
        }

        // Return true if we can form at least 'k' piles, otherwise false
        return pileCount >= k;
    }

public:
    // Main function to find the maximum number of candies that can be allocated to each child
    int maximumCandies(vector<int>& candies, long long k) {

        // Get the number of candy piles
        int n = candies.size();

        // Set initial search range for the number of candies per child
        int l = 0, r = *max_element(candies.begin(), candies.end());

        // Store the last valid i
        int maxCandies = 0; 

        // Iterate from min number of candies to max number of candies
        for (int i = l; i <= r; i++) {

            // Check if it's possible to allocate 'k' piles with at least 'i' candies each
            if (!isPossible(candies, k, i)) {

                // Return the last valid i, as it was the maximum number of candies possible
                return maxCandies;
            }

            // Update maxCandies to the last valid value
            maxCandies = i; 
        }

        // If we reach here, return the max possible value
        return maxCandies;
    }
};

2. Maximum Candies Allocated to K Children solution in Java Try on Compiler
import java.util.Arrays;

class Solution {
    // Function to check if it's possible to make 'k' piles where each pile has at least 'm' candies
    public boolean isPossible(int[] candies, long k, int m) {
        
        // If 'm' is 0, it's always possible as we can create an infinite number of piles
        if (m == 0) return true;

        long pileCount = 0;

        // Loop through each candy pile
        for (int candy : candies) {
            // Count the number of piles we can form by dividing the candies in this pile by 'm'
            pileCount += (candy / m);
        }

        // Return true if we can form at least 'k' piles, otherwise false
        return pileCount >= k;
    }

    // Main function to find the maximum number of candies that can be allocated to each child
    public int maximumCandies(int[] candies, long k) {

        // Get the number of candy piles
        int n = candies.length;

        // Set initial search range for the number of candies per child
        int l = 0, r = Arrays.stream(candies).max().getAsInt();

        int maxCandies = 0; // Store the last valid i

        // Iterate from min number of candies to max number of candies
        for (int i = l; i <= r; i++) {

            // Check if it's possible to allocate 'k' piles with at least 'i' candies each
            if (!isPossible(candies, k, i)) {

                // Return the last valid i, as it was the maximum number of candies possible
                return maxCandies;
            }
            
            maxCandies = i; // Update maxCandies to the last valid value
        }

        // If we reach here, return the max possible value
        return maxCandies;
    }
}

3. Maximum Candies Allocated to K Children solution in Python Try on Compiler
class Solution:
    # Function to check if it's possible to make 'k' piles where each pile has at least 'm' candies
    def isPossible(self, candies, k, m):

        # If 'm' is 0, it's always possible as we can create an infinite number of piles
        if m == 0:
            return True

        pileCount = 0

        # Loop through each candy pile
        for candy in candies:

            # Count the number of piles we can form by dividing the candies in this pile by 'm'
            pileCount += (candy // m)

        # Return True if we can form at least 'k' piles, otherwise False
        return pileCount >= k

    # Main function to find the maximum number of candies that can be allocated to each child
    def maximumCandies(self, candies, k):

        # Get the number of candy piles
        n = len(candies)

        # Set initial search range for the number of candies per child
        l, r = 0, max(candies)

        maxCandies = 0  # Store the last valid 'i'

        # Iterate from 0 to max number of candies
        for i in range(l, r + 1):

            # Check if it's possible to allocate 'k' piles with at least 'i' candies each
            if not self.isPossible(candies, k, i):
                
                # Return the last valid 'i', as it was the maximum number of candies possible
                return maxCandies

            maxCandies = i  # Update maxCandies to the last valid value

        # If we reach here, return the max possible value
        return maxCandies

4. Maximum Candies Allocated to K Children solution in Javascript Try on Compiler
/**
 * @param {number[]} candies
 * @param {number} k
 * @return {number}
 */
// Function to check if it's possible to make 'k' piles where each pile has at least 'm' candies
var isPossible = function (candies, k, m) {

    // If 'm' is 0, it's always possible as we can create an infinite number of piles
    if (m === 0) return true;

    let pileCount = 0;

    // Loop through each candy pile
    for (let i = 0; i < candies.length; i++) {
        // Count the number of piles we can form by dividing the candies in this pile by 'm'
        pileCount += Math.floor(candies[i] / m);
    }

    // Return true if we can form at least 'k' piles, otherwise false
    return pileCount >= k;
}

var maximumCandies = function (candies, k) {
    // Get the number of candy piles
    let n = candies.length;

    // Set initial search range for the number of candies per child
    let l = 0, r = Math.max(...candies);
    let maxCandies = 0; // Store the last valid 'i'

    // Iterate from 0 to max number of candies
    for (let i = l; i <= r; i++) {

        // Check if it's possible to allocate 'k' piles with at least 'i' candies each
        if (!isPossible(candies, k, i)) {
            // Return the last valid 'i', as it was the maximum number of candies possible
            return maxCandies;
        }

        maxCandies = i; // Update maxCandies to the last valid value
    }

    // If we reach here, return the max possible value
    return maxCandies;
};

Complexity Analysis of Maximum Candies Allocated to K Children (brute force):

Time Complexity: O(max(candies) * n)

The time complexity of the given solution can be broken down into two main parts:

  1. Iterating Over Possible Values for Candies per Child (i):
    The outer loop iterates from l = 0 (minimum possible candies per child) to r = max(candies) (maximum candies per child).
    This results in O(r - l + 1) = O(max(candies) - 0 + 1) = O(max(candies)) iterations in the worst case.
  2. Calling the Helper Function (isPossible) for Each i:
    For each value of i, we call the isPossible function.
    In the isPossible function, we loop through the candies array to count how many piles of at least i candies can be formed. This takes O(n) time, where n is the length of the candies array.

Combined Time Complexity:

  • Outer Loop: Iterates from 0 to max(candies)O(max(candies))
  • Inner Loop (isPossible): For each iteration of the outer loop, we call the isPossible function, which takes O(n) time.

Thus, the overall time complexity is: O(max(candies) * n)

Where:

  • max(candies) is the maximum number of candies in the candies array.
  • n is the number of elements (candy piles) in the candies array.

Space Complexity: O(n)

  1. Auxiliary Space Complexity: O(1)
    The algorithm only uses a few integer variables. These are just primitive variables that occupy O(1) space.
    Therefore, the auxiliary space complexity is O(1).
  2. Total Space Complexity: O(n)
    Since we do not create any new data structures apart from the input candies, the total space complexity is O(n), where n is the size of the input array.
    Therefore, the total space complexity is O(n).

Will Brute Force Work Against the Given Constraints? 

For the current solution, the time complexity is O(max(candies) * n), where n is the number of piles (with an upper limit of 10⁵), and max(candies) is the maximum value in the candies array (with an upper limit of 10⁷). In the worst-case scenario, max(candies) could be as large as 10⁷, which leads to a time complexity of O(max(candies) * n).

This time complexity can become inefficient when the maximum number of candies in a pile is large, particularly when max(candies) is close to its upper bound (10⁷), and N is large (up to 10⁵). In such cases, the algorithm may perform a large number of operations (nearly 10¹²) and become impractical for large inputs.

This solution may not execute efficiently for all test cases, particularly when max(candies) is near its upper limit. While it may work for inputs with smaller values for max(candies), it could exceed the time limits for large inputs where the value of max(candies) is close to its maximum constraint.

In competitive programming environments, the typical time complexity limit is around 10⁶ operations per test case. Therefore, for inputs with large values in the candies array, this time complexity could lead to inefficient execution. To make the solution more optimal and handle all possible cases, optimizations such as binary search or other techniques could be considered to reduce the time complexity further.

How to optimize it?

In the previous approach, we checked every possible value of the number of candies each child can get (from 0 to max(candies)) and verified if it was possible to distribute the candies such that at least k piles were formed, each with at least m candies. This gave us O(n * max(candies)) time complexity, which was too slow and caused TLE (Time Limit Exceeded).

Now, let’s think about improving this.
The main issue was that we checked every possible value of the number of candies from 0 to max(candies), which took a lot of time.

Can we make this part faster?

Yes! Here’s the hint:

We are searching for the maximum number of candies each child can get that still allows us to form k piles. We know this maximum lies between 0 (minimum candies per child) and max(candies) (maximum candies in a pile)

Now that we know the two endpoints, 0 and max(candies), let's make a few observations:

  • The data structure is sorted:
    The range of possible candies per child is naturally sorted from 0 to max(candies).
  • The search space is monotonic:
    • If a certain number of candies per child allows us to make k piles, then any smaller number will also work.
    • If a certain number does not allow us to make k piles, then any larger number will also fail.
    • For the example with the candies [5, 8, 6] and k = 3, the algorithm will fail to form 3 piles with at least 6 candies each for value 5 (F). Starting from 5, it will succeed in making the piles (T, T, T), and the search will find that the maximum number of candies per child is 5. This illustrates the monotonic property: once a number works, it will continue to work for larger numbers.
  • The middle element helps minimize or maximize the search space:
    If we take the middle value of the current range and check if it works (i.e., can we make at least k piles with at least m candies each), we can narrow the search space:
    If it works, we move to the right half to find a larger valid number of candies.
    If it doesn’t work, we move to the left half to find a smaller valid number of candies.

If we plot a graph with the range of possible candies per child on the x-axis and the number of piles we can form with x candies (f(x)) on the y-axis, we can observe the following:

  • For a given number of candies, we can either make k piles or not.
  • Before the maximum valid number (denoted as maxcandies), we can form k or more piles. This is because for any number of candies less than maxcandies, the conditions are such that we can start forming the required number of piles, and this condition will continue to hold true as we go lower.
  • Once we reach maxcandies, we cannot form k piles with fewer candies. This is because, for any number of candies less than maxcandies, the conditions for making k piles are not met.
maximum-candies-allocated-to-k-children-graph

Thus, maxcandies represents the largest number of candies each child can get while still being able to make k piles. Once this number is found, making k piles remains feasible for any number less than or equal to maxcandies.

With these points in mind, it's clear that instead of linearly checking all possible values from 0 to max(candies), we can take the middle value and continually reduce the search space.

Does this approach remind you of something you've seen before?

Yes, we are applying binary search here. By leveraging the sorted and monotonic properties of the range of possible candies per child, we efficiently narrow down the search space to find the maximum number that works instead of checking each value linearly.

Binary search can help us quickly find the maximum number of candies each child can get while still allowing us to make k piles.

We can simply use binary search to determine the maximum number of candies each child can get to make k piles.

Start by taking the middle value between low (0) and high (max(candies)). If this mid value satisfies the condition that we can make k piles with at least mid candies each, we store it as a potential answer and narrow the search space to the right half, looking for a larger valid value. Otherwise, we move the search to the left half to find a smaller valid value. We continue this process as long as low <= high. Once the condition breaks, the stored answer is returned as the maximum number of candies each child can get.

Once the condition breaks, the stored answer is returned as the maximum number of candies that can be given to each child.

By using binary search, we can cut the search space in half at each step, which makes the solution much faster and avoids the TLE issue.

Let us understand this with a videa,

0:00
/2:12

maximum-candies-allocated-to-k-children-Animation Explaination

Let's understand with an example:

Maximum Candies Allocated to K Children example:

Let's walk through a concise dry run of the binary search approach with the example candies = [1, 2, 3, 4, 10] and k = 5:

  1. Initial Setup:
    candies = [1, 2, 3, 4, 10], k = 5
    l = 0 (min(candies))
    r = 10 (max(candies))
  2. First Iteration:
    mid = (0 + 10) / 2 = 5
    Call isPossible(candies, k, 5):
    Count piles: 1/5 + 2/5 + 3/5 + 4/5 + 10/5 = 0 + 0 + 0 + 0 + 2 = 2
    Since 2 < 5, it is not possible to make 5 piles with at least 5 candies.
    Move the search range to l = 0, r = 4.
  3. Second Iteration:
    mid = (0 + 4) / 2 = 2
    Call isPossible(candies, k, 2):
    Count piles: 1/2 + 2/2 + 3/2 + 4/2 + 10/2 = 0 + 1 + 1 + 2 + 5 = 9
    Since 9 >= 5, it is possible to make 5 piles with at least 2 candies.
    Move the search range to l = 3, r = 4.
  4. Third Iteration:
    mid = (3 + 4) / 2 = 3
    Call isPossible(candies, k, 9):
    Count piles: 1/3 + 2/3 + 3/3 + 4/3 + 10/3 = 0 + 0 + 1 + 1 + 3 = 5
    Since 5 >= 5, it is possible to make 5 piles with at least 3 candies.
    Move the search range to l = 4, r = 4.
  5. Fourth Iteration:
    mid = (4 + 4) / 2 = 4
    Call isPossible(candies, k, 4):
    Count piles: 1/4 + 2/4 + 3/4 + 4/4 + 10/4 = 0 + 0 + 0 + 1 + 2 = 3
    Since 3 < 5, it is not possible to make 5 piles with at least 4 candies.
    Move the search range to l = 5, r = 4, since l > r, break the loop

Since 3 is the maximum number of candies per child that allows us to form at least 5 piles, the answer is 3.

How to code it up:

Define the Helper Function (isPossible):
Input: candies (vector of integers), k (number of piles), m (candies per pile).
Process:
If m is 0, return true (since we can create an infinite number of piles).
Initialize pileCount to 0.
Loop through each candy pile and calculate how many piles can be made with at least m candies.
Return true if pileCount is greater than or equal to k, otherwise return false.

Define the Main Function (maximumCandies):
Input: candies (vector of integers), k (number of piles).
Process:
Initialize the lower (l) and upper (r) bounds for the binary search:
l = 0 (minimum possible candies per pile).
r = max(candies) (maximum possible candies per pile).
Set a variable maxcandies to store the maximum candies per child found.
Use binary search:
Calculate mid as the average of l and r.
Call isPossible with mid to check if it's possible to make at least k piles.
If it's possible, update maxcandies and move the left bound (l) to mid + 1 to search for a larger value.
If not possible, move the right bound (r) to mid - 1 to search for a smaller value.
Return maxcandies as the result.

Find the Maximum Candies Allocated to K Children LeetCode solution below.

Maximum Candies Allocated to K Children solution / Code Implementation
1. Maximum Candies Allocated to K Children solution in c++ Try on Compiler
class Solution {
    // Function to check if it's possible to make 'k' piles where each pile has at least 'm' candies
    bool isPossible(vector<int> &candies, long long k, int m)
    {
        // If 'm' is 0, it's always possible as we can create an infinite number of piles
        if(m == 0)  return true;

        long long pileCount = 0;

        // Loop through each candy pile
        for(int i=0; i<candies.size(); i++)
        {   
            // Count the number of piles we can form by dividing the candies in this pile by 'm'
            pileCount += (candies[i]/m);
        }

        // Return true if we can form at least 'k' piles, otherwise false
        return pileCount >= k;
    }
public:
    // Main function to find the maximum number of candies that can be allocated to each child
    int maximumCandies(vector<int>& candies, long long k) {
        // Initialize the lower and upper bounds for binary search
        int l = 0, r = *max_element(candies.begin(), candies.end());
        
        // Variable to store the maximum possible candies per child
        int maxcandies = 0;

        // Perform binary search to find the maximum candies per child
        while(l <= r)
        {
            // Find the middle point
            int mid = l + (r-l)/2;
            
            // Check if it's possible to form at least 'k' piles with 'mid' candies per pile
            if(isPossible(candies, k, mid))
            {
                // If possible, store the value and search for a larger value in the right half
                maxcandies = mid;
                l = mid + 1;
            }
            else
                // If not possible, search in the left half
                r = mid - 1;
        }

        // Return the maximum candies per child
        return maxcandies;
    }
};

2. Maximum Candies Allocated to K Children solution in Java Try on Compiler
class Solution {

    // Function to check if it's possible to make 'k' piles where each pile has at least 'm' candies
    public boolean isPossible(int[] candies, long k, int m) {

        // If 'm' is 0, it's always possible as we can create an infinite number of piles
        if (m == 0) return true;

        long pileCount = 0;

        // Loop through each candy pile
        for (int i = 0; i < candies.length; i++) {

            // Count the number of piles we can form by dividing the candies in this pile by 'm'
            pileCount += (candies[i] / m);
        }

        // Return true if we can form at least 'k' piles, otherwise false
        return pileCount >= k;
    }

    // Main function to find the maximum number of candies that can be allocated to each child
    public int maximumCandies(int[] candies, long k) {

        // Initialize the lower and upper bounds for binary search
        int l = 0, r = Integer.MIN_VALUE;

        // Find the maximum number of candies
        for (int i = 0; i < candies.length; i++) {
            r = Math.max(r, candies[i]);
        }
        
        // Variable to store the maximum possible candies per child
        int maxcandies = 0;

        // Perform binary search to find the maximum candies per child
        while (l <= r) {
            // Find the middle point
            int mid = l + (r - l) / 2;

            // Check if it's possible to form at least 'k' piles with 'mid' candies per pile
            if (isPossible(candies, k, mid)) {

                // If possible, store the value and search for a larger value in the right half
                maxcandies = mid;
                l = mid + 1;
            } else {
                
                // If not possible, search in the left half
                r = mid - 1;
            }
        }

        // Return the maximum candies per child
        return maxcandies;
    }
}

3. Maximum Candies Allocated to K Children solution in Python Try on Compiler
class Solution:
    # Function to check if it's possible to make 'k' piles where each pile has at least 'm' candies
    def isPossible(self, candies, k, m):

        # If 'm' is 0, it's always possible as we can create an infinite number of piles
        if m == 0:
            return True

        pileCount = 0

        # Loop through each candy pile
        for candy in candies:

            # Count the number of piles we can form by dividing the candies in this pile by 'm'
            pileCount += (candy // m)

        # Return True if we can form at least 'k' piles, otherwise False
        return pileCount >= k

    # Main function to find the maximum number of candies that can be allocated to each child
    def maximumCandies(self, candies, k):

        # Initialize the lower and upper bounds for binary search
        l, r = 0, max(candies)
        
        # Variable to store the maximum possible candies per child
        maxcandies = 0

        # Perform binary search to find the maximum candies per child
        while l <= r:
            # Find the middle point
            mid = l + (r - l) // 2
            
            # Check if it's possible to form at least 'k' piles with 'mid' candies per pile
            if self.isPossible(candies, k, mid):

                # If possible, store the value and search for a larger value in the right half
                maxcandies = mid
                l = mid + 1
            else:
                
                # If not possible, search in the left half
                r = mid - 1

        # Return the maximum candies per child
        return maxcandies

4. Maximum Candies Allocated to K Children solution in Javascript Try on Compiler
/**
 * @param {number[]} candies
 * @param {number} k
 * @return {number}
 */
// Function to check if it's possible to make 'k' piles where each pile has at least 'm' candies
var isPossible = function (candies, k, m) {

    // If 'm' is 0, it's always possible as we can create an infinite number of piles
    if (m === 0) return true;

    let pileCount = 0;

    // Loop through each candy pile
    for (let i = 0; i < candies.length; i++) {

        // Count the number of piles we can form by dividing the candies in this pile by 'm'
        pileCount += Math.floor(candies[i] / m);
    }

    // Return true if we can form at least 'k' piles, otherwise false
    return pileCount >= k;
}

var maximumCandies = function (candies, k) {

    // Initialize the lower and upper bounds for binary search
    let l = 0, r = Math.max(...candies);

    // Variable to store the maximum possible candies per child
    let maxcandies = 0;

    // Perform binary search to find the maximum candies per child
    while (l <= r) {
        // Find the middle point
        let mid = l + Math.floor((r - l) / 2);

        // Check if it's possible to form at least 'k' piles with 'mid' candies per pile
        if (isPossible(candies, k, mid)) {

            // If possible, store the value and search for a larger value in the right half
            maxcandies = mid;
            l = mid + 1;
        } else {
            
            // If not possible, search in the left half
            r = mid - 1;
        }
    }

    // Return the maximum candies per child
    return maxcandies;
};

Time Complexity : O(n * log(max(candies)))

The time complexity analysis for the given solution is as follows:

1. Binary Search:
The binary search is applied on the possible number of candies per child, which ranges from 0 to the maximum number of candies in the array candies.
The range of possible values is from 0 to max(candies), where max(candies) is O(n), since max(candies) can be found in O(n) time.
However, the binary search will run in log(max(candies)) iterations.

Therefore, the binary search step contributes O(log(max(candies))) time.

2. isPossible Function:
In each iteration of the binary search, the isPossible function is called.
Inside the isPossible function, we iterate over the candies array once to count the possible piles.
The loop runs for n elements in candies, so the time complexity of the isPossible function is O(n).

3. Overall Time Complexity:
The binary search runs in O(log(max(candies))) iterations.
In each iteration, the isPossible function runs in O(n) time.
Thus, the overall time complexity is the product of these two factors: O(n * log(max(candies))).

The time complexity of the algorithm is O(n * log(max(candies))), where n is the number of elements in the candies array and max(candies) is the maximum value in the array.

Space Complexity : O(n)

  1. Auxiliary Space Complexity: O(1)
    The algorithm only uses a few integer variables. These are just primitive variables that occupy O(1) space.
    Therefore, the auxiliary space complexity is O(1).
  2. Total Space Complexity: O(n)
    Since we do not create any new data structures apart from the input candies, the total space complexity is O(n), where n is the size of the input array.
    Therefore, the total space complexity is O(n).

Similar Problems

Now we have successfully tackled this problem, let's try these similar problems.

Koko loves to eat bananas. There are n piles of bananas, the ith pile has piles[i] bananas. The guards have gone and will come back in h hours.Koko can decide her bananas-per-hour eating speed of k. Each hour, she chooses some pile of bananas and eats k bananas from that pile. If the pile has less than k bananas, she eats all of them instead and will not eat any more bananas during this hour.Koko likes to eat slowly but still wants to finish eating all the bananas before the guards return.Return the minimum integer k such that she can eat all the bananas within h hours.

A conveyor belt has packages that must be shipped from one port to another within D days.The ith package on the conveyor belt has a weight of weights[i]. Each day, we load the ship with packages on the conveyor belt (in the order given by weights). We may not load more weight than the maximum weight capacity of the ship.Return the least weight capacity of the ship that will result in all the packages on the conveyor belt being shipped within D days.

💡
Showcase your skills by joining LearnYard Technologies FZ-LLC as a Technical Content Writer. Apply now and inspire the next generation of learners—fill out the form: https://forms.gle/CGDsbGkcapSfvXKM8