Minimum Limit of Balls in a Bag

MediumLeetcode

Minimum Limit of Balls in a Bag

Pattern: Binary search on answer

Idea:

Variations :


πŸ’» Code

Boundary style Binary Search

def minimumSize(nums, maxOperations):
    low = 1
    high = max(nums)

    def feasible(limit):
        operations = 0

        for balls in nums:
            operations += (balls - 1) // limit

            if operations > maxOperations:
                return False

        return True

    while low < high:
        mid = low + (high - low) // 2

        if feasible(mid):
            high = mid
        else:
            low = mid + 1

    return low

Time complexity - O(n log M ) , M = max(nums) Aux. Space complexity - O(1)


LeetCode 1760 β€” Binary Search on Answer + Counting

You have bags containing different numbers of balls. In one operation, you can split a bag into two non-empty bags.

Find the minimum possible maximum number of balls in any bag after performing at most maxOperations splits.


Key Idea

We want to:

Minimize the maximum number of balls in a bag.

Guess a candidate maximum size limit and ask:

How many split operations are required to make every bag contain at most limit balls?

For a bag containing x balls:

operations(x)=⌈xlimitβŒ‰βˆ’1operations(x) = \left\lceil\frac{x}{limit}\right\rceil - 1

Equivalent integer form:

operations(x)=⌊xβˆ’1limitβŒ‹operations(x) = \left\lfloor\frac{x-1}{limit}\right\rfloor

So:

totalOperations=βˆ‘i⌊nums[i]βˆ’1limitβŒ‹totalOperations = \sum_i \left\lfloor\frac{nums[i]-1}{limit}\right\rfloor

limit is feasible when:

totalOperations≀maxOperationstotalOperations \le maxOperations

Why ceil(x / limit) - 1?

Suppose a bag has 9 balls and:

limit = 3

We need:

[3] [3] [3]

That’s 3 bags, requiring:

3 - 1 = 2 splits

Therefore:

⌈93βŒ‰βˆ’1=2\left\lceil\frac{9}{3}\right\rceil-1 = 2

For:

x = 10, limit = 3

we need:

[3] [3] [4]

3 bags β†’ 2 splits:

⌈10/3βŒ‰βˆ’1=3βˆ’1=2\lceil10/3\rceil-1 = 3-1=2

Why Binary Search Works

As limit increases, fewer splits are necessary.

limit:
1  2  3  4  5  6 ...
operations:
↑
many -----------β†’ fewer

feasible:
F  F  F  T  T  T ...
         ↑
    first feasible

Therefore:

Smaller limit β†’ harder β†’ more operations
Larger limit β†’ easier β†’ fewer operations

So we search for the first feasible limit.


Search Space

Lower bound

low = 1

Every bag must contain at least one ball.

Upper bound

high = max(nums)

With no splits, the largest bag already gives a valid upper bound.

Therefore:

[1, max(nums)]

Approach

For each candidate limit:

  1. Calculate how many operations each bag needs.

  2. Stop early if operations exceed maxOperations.

  3. If total operations are within the limit, the candidate is feasible.

  4. Binary-search the smallest feasible limit.


Python Solution β€” Implicit Answer Style

def minimumSize(nums, maxOperations):
    low = 1
    high = max(nums)

    def feasible(limit):
        operations = 0

        for balls in nums:
            operations += (balls - 1) // limit

            if operations > maxOperations:
                return False

        return True

    while low < high:
        mid = low + (high - low) // 2

        if feasible(mid):
            high = mid
        else:
            low = mid + 1

    return low

Why (balls - 1) // limit?

It is an integer-only way of computing:

⌈ballslimitβŒ‰βˆ’1\left\lceil\frac{balls}{limit}\right\rceil - 1

This is a particularly useful formula to remember.


Explicit Answer Style

def minimumSize(nums, maxOperations):
    low = 1
    high = max(nums)
    ans = high

    def feasible(limit):
        operations = 0

        for balls in nums:
            operations += (balls - 1) // limit

            if operations > maxOperations:
                return False

        return True

    while low <= high:
        mid = low + (high - low) // 2

        if feasible(mid):
            ans = mid
            high = mid - 1
        else:
            low = mid + 1

    return ans

Both are equivalent.

For this problem, the implicit first-True version is particularly clean.


Dry Run

nums = [9]
maxOperations = 2

Try:

limit = 3

Required operations:

(9βˆ’1)//3=8//3=2(9-1)//3 = 8//3 = 2

Feasible.

Try:

limit = 2
(9βˆ’1)//2=8//2=4(9-1)//2 = 8//2 = 4

4 > 2 β†’ not feasible.

Therefore:

answer = 3

The bag can become:

[3] [3] [3]

using exactly 2 operations.


Complexity

Let:

  • nn = number of bags

  • MM = max(nums)

Each feasibility check:

O(n)O(n)

Binary search:

O(log⁑M)O(\log M)

Therefore:

O(nlog⁑M)\boxed{O(n\log M)}

Auxiliary Space

O(1)\boxed{O(1)}

Important Quirks

1. Number of operations β‰  number of resulting bags

If a bag needs k final bags:

operations=kβˆ’1operations = k - 1

This is why:

⌈x/LβŒ‰βˆ’1\boxed{\left\lceil x/L\right\rceil - 1}

is used.


2. operations <= maxOperations

We don’t need to use all operations.

operations <= maxOperations

is sufficient.


3. Splitting can be done optimally without simulating it

You might initially think you need to actually perform the splits.

You don’t.

For a fixed limit, the mathematical formula directly tells us the minimum number of splits required.

This makes the validator O(n)O(n).


Connection to Previous Problems

This is closely related to the two problems you’ve just studied:

Smallest Divisor

βˆ‘i⌈xidβŒ‰β‰€threshold\sum_i \left\lceil\frac{x_i}{d}\right\rceil \le threshold

Minimized Maximum Products

βˆ‘i⌈xiXβŒ‰β‰€stores\sum_i \left\lceil\frac{x_i}{X}\right\rceil \le stores

Balls in a Bag

βˆ‘i(⌈xiXβŒ‰βˆ’1)≀operations\sum_i \left( \left\lceil\frac{x_i}{X}\right\rceil-1 \right) \le operations

All three follow:

Candidate X
    ↓
Calculate required resource
    ↓
Required <= available?
    ↓
FFFFTTTT
    ↓
First True

The key difference is what the validator counts.


Important Variations

⭐ Same family

  • Smallest Divisor Given a Threshold β†’ quotient/count calculation

  • Minimized Maximum of Products β†’ containers required

  • Capacity to Ship Packages β†’ greedy grouping

  • Split Array Largest Sum β†’ greedy partition

The reusable pattern

Minimize the maximum β†’ guess the maximum β†’ calculate the resources needed β†’ check whether resources fit β†’ first feasible.


Common Mistakes

  • ❌ Using balls // limit as the number of operations.

  • ❌ Forgetting the -1 in ceil(balls / limit) - 1.

  • ❌ Simulating every split.

  • ❌ Using operations == maxOperations.

  • ❌ Searching for the exact original bag sizes instead of [1, max(nums)].

  • ❌ Forgetting that the predicate is first True.


Pattern Recognition

When you see:

β€œMinimize the maximum size after performing at most K operations, where each operation splits/reduces something.”

Think:

MINIMIZE THE MAXIMUM
        ↓
Guess maximum allowed size X
        ↓
How many operations are minimally required?
        ↓
operations <= K ?
        ↓
FFFFTTTT
        ↓
FIRST TRUE

Mental hook

β€œDon’t simulate the splits. For a candidate maximum X, calculate how many splits are mathematically necessary.”

This is an important evolution of the Minimize the Maximum pattern: the validator doesn’t always need greedy simulationβ€”it can sometimes be reduced to a direct mathematical counting formula.

Local Graph View

Start typing to search
Try: two sum or #Arrays or #Amazon