Maximum Running Time of N Computers

hard binary search greedy

Problem

You have n identical computers and a pile of batteries, where batteries[i] can power one computer for that many minutes. At any moment you may swap batteries between computers — swapping is instant and unlimited — but charge is never regained: a battery's remaining minutes only go down while it powers a machine, and one battery can drive only one computer at a time.

Return the maximum number of whole minutes you can keep all n computers running simultaneously. Constraints: 1 ≤ n ≤ batteries.length ≤ 10⁵, 1 ≤ batteries[i] ≤ 10⁹.

Inputn = 2, batteries = [3, 3, 3]
Output4
For t = 4 each battery contributes min(3, 4) = 3, giving 9 ≥ 2·4 = 8 energy, so 4 minutes is achievable by swapping; t = 5 would need 10 > 9 total energy.

def max_run_time(n, batteries):
    total = sum(batteries)
    lo, hi = 1, total // n
    ans = 0
    while lo <= hi:
        mid = (lo + hi) // 2
        usable = sum(min(b, mid) for b in batteries)
        if usable >= n * mid:
            ans = mid
            lo = mid + 1
        else:
            hi = mid - 1
    return ans
function maxRunTime(n, batteries) {
  const total = batteries.reduce((a, b) => a + b, 0);
  let lo = 1, hi = Math.floor(total / n), ans = 0;
  while (lo <= hi) {
    const mid = Math.floor((lo + hi) / 2);
    let usable = 0;
    for (const b of batteries) usable += Math.min(b, mid);
    if (usable >= n * mid) {
      ans = mid;
      lo = mid + 1;
    } else {
      hi = mid - 1;
    }
  }
  return ans;
}
long maxRunTime(int n, int[] batteries) {
    long total = 0;
    for (int b : batteries) total += b;
    long lo = 1, hi = total / n, ans = 0;
    while (lo <= hi) {
        long mid = (lo + hi) / 2;
        long usable = 0;
        for (int b : batteries) usable += Math.min(b, mid);
        if (usable >= n * mid) {
            ans = mid;
            lo = mid + 1;
        } else {
            hi = mid - 1;
        }
    }
    return ans;
}
long long maxRunTime(int n, vector<int>& batteries) {
    long long total = 0;
    for (int b : batteries) total += b;
    long long lo = 1, hi = total / n, ans = 0;
    while (lo <= hi) {
        long long mid = (lo + hi) / 2;
        long long usable = 0;
        for (int b : batteries) usable += min((long long)b, mid);
        if (usable >= (long long)n * mid) {
            ans = mid;
            lo = mid + 1;
        } else {
            hi = mid - 1;
        }
    }
    return ans;
}
Time: O(m · log(sum / n)) Space: O(1)