直接根据条件求解答案比较困难,因此考虑使用二分答案法,在所以可能的结果之间进行二分查找,每次查找完后验证是否符合条件。若符合,则 l = mid + 1;若不符合,r = mid. 最终找到第一个不符合条件的结果,它减一也就是符合条件的最大结果。
那么问题的关键在于如何确定某个数 t 是否符合条件。假设该数为 t,即所有电脑需要同时运行 t 分钟,因为一个电池只能同时给一台电脑供电,因此一个电池可供电的最长时间将会受到 t 的限制,因此一个电池的可供电的最长时间为 min(t, batteries[i])。根据这个条件,我们可以求出所有电池可供电的最长时间的总和 S,最后判断 S 是否大于等于 n * t 来得到该值是否符合条件。
为什么可以直接根据 S 和 n * t 的大小关系进行判断呢?我们可以将 N 台电脑的供电过程想象成一个串行的过程,先使用若干电池给第一台电脑供电,然后继续使用其它电池给第二台电脑供电,以此类推。事实上,各电脑的供电过程是并行的,而我们刚刚的电池分配方案间并不会冲突,因此是可行的。
classSolution { public: longlongmaxRunTime(int n, vector<int>& batteries){ auto canRun = [&](longlong t) { longlong sum = 0; for (constauto& battery : batteries) { sum += min(static_cast<longlong>(battery), t); } return sum / t >= n; };
longlong sumBat = accumulate(batteries.begin(), batteries.end(), 0L); longlong l = 1, r = sumBat / n + 1; while (l < r) { longlong mid = (l + r) / 2; if (canRun(mid)) l = mid + 1; else r = mid; } return l - 1; } };