2226. 每个小孩最多能分到多少糖果
提示:
- 1 < = c a n d i e s . l e n g t h < = 1 0 5 1 <= candies.length <= 10^5 1<=candies.length<=105
- 1 < = c a n d i e s [ i ] < = 1 0 7 1 <= candies[i] <= 10^7 1<=candies[i]<=107
- 1 < = k < = 1 0 1 2 1 <= k <= 10^12 1<=k<=1012
思路:
- 统计所有糖果数量
sum
- 若
sum < k
,说明糖果太少,一人一颗都不够~ - 否则,每人至少能分到一颗糖果,至多能分到
sum/k
颗糖果
- 若
- 二分遍历
- 计算对每堆糖果都按照
mid
分时,能得到的堆数为heap
- 每堆都按照mid分的时候,若堆数小于小孩人数,说明无法保证每个小孩都能取一堆,此时应该缩小每堆 糖果数量,即
right = mid - 1;;
- 否则,说明需要增加每堆 糖果数量,即
left = mid + 1;
- 计算对每堆糖果都按照
- 最终,返回
right
即为所求
class Solution {
public int maximumCandies(int[] candies, long k) {
int n = candies.length;
long sum = 0L;
for (int candy : candies) sum += candy;
// 糖果太少,一人一颗都不够~
if (sum < k) {
return 0;
}
// 此时,每人至少能分到一颗糖果,至多能分到sum/k颗糖果
long left = 1;
long right = sum / k;
while (left <= right) {
long mid = left + (right - left) / 2;
long heap = 0; // 对每堆糖果都按照mid分时,能得到的堆数为heap
for (int num : candies) {
heap += (num / mid);
}
// 每堆都按照mid分的时候,堆数小于小孩人数,无法保证每个小孩都能取一堆,此时应该缩小每堆 糖果数量
if (heap < k) {
right = mid - 1;
} else {
left = mid + 1;
}
}
return (int) right;
}
}
- 时间复杂度:
O
(
n
)
O(n)
O(n) (线性扫描
candies
) - 空间复杂度: O ( 1 ) O(1) O(1)