Minimized Maximum of Products Distributed to Any Store

medium array binary search greedy

Problem

There are n stores and m product types with counts quantities[i]. Distribute all products so each store gets at most one product type (any amount). Let x be the largest number of products handed to any single store. Return the minimum possible x.

Inputn = 6, quantities = [11, 6]
Output3
Type 0 (11) over 4 stores as 2,3,3,3 and type 1 (6) over 2 stores as 3,3 — six stores, max load 3.

def minimizedMaximum(n, quantities):
    def can(k):                         # max k per store?
        stores = 0
        for q in quantities:
            stores += (q + k - 1) // k  # ceil(q / k)
        return stores <= n
    lo, hi = 1, max(quantities)
    while lo < hi:
        mid = (lo + hi) // 2
        if can(mid):
            hi = mid                    # mid works, try smaller
        else:
            lo = mid + 1                # need bigger cap
    return lo
function minimizedMaximum(n, quantities) {
  const can = (k) => {                  // max k per store?
    let stores = 0;
    for (const q of quantities)
      stores += Math.ceil(q / k);       // stores for this type
    return stores <= n;
  };
  let lo = 1, hi = Math.max(...quantities);
  while (lo < hi) {
    const mid = (lo + hi) >> 1;
    if (can(mid)) hi = mid;             // mid works, try smaller
    else lo = mid + 1;                  // need bigger cap
  }
  return lo;
}
class Solution {
    public int minimizedMaximum(int n, int[] quantities) {
        int lo = 1, hi = 0;
        for (int q : quantities) hi = Math.max(hi, q);
        while (lo < hi) {
            int mid = (lo + hi) >>> 1;
            if (can(quantities, n, mid)) hi = mid;
            else lo = mid + 1;
        }
        return lo;
    }
    private boolean can(int[] quantities, int n, int k) {
        long stores = 0;
        for (int q : quantities) stores += (q + k - 1) / k;
        return stores <= n;
    }
}
class Solution {
public:
    int minimizedMaximum(int n, vector<int>& quantities) {
        int lo = 1, hi = 0;
        for (int q : quantities) hi = max(hi, q);
        auto can = [&](int k) {
            long long stores = 0;
            for (int q : quantities) stores += (q + k - 1) / k;
            return stores <= n;
        };
        while (lo < hi) {
            int mid = (lo + hi) / 2;
            if (can(mid)) hi = mid;
            else lo = mid + 1;
        }
        return lo;
    }
};
Time: O(m log(max q)) Space: O(1)