解题思路
由于糖果分配符合 的规律
可以计算出分配糖果的和为
解一元二次方程的正根,可以计算出
所以可以计算出一共分配了 r
到 r+1
(边界情况) 轮
算法流程
-
先计算前
r
轮的分配 -
再遍历模拟单独处理
r+1
轮的分配
复杂度分析
- 时间复杂度
- 空间复杂度
代码
class Solution {
public int[] distributeCandies(int candies, int num_people) {
int[] ans = new int[num_people];
// 计算出一共可以分配多少次糖果, 1+2+3+...+n = (n+1)n/2 = candies => n = (-1 + sqrt(1-4*(-2*candies)))/2
int N = (int)((Math.sqrt(1.0+8.0*candies)-1)/2);
// 一共可以分配多少轮糖果
int round = N / num_people;
// 处理边界数据
int leftCandies = candies;
//System.out.println(N + ", round=" + round);
//先按照可以全部分完的整数分配
for (int i = 0; i < num_people; ++i) {
// for (int r = 0; r < round; ++ r) {
// ans[i] += (i+1) + r * num_people;
// }
ans[i] = (i+1) * round + num_people * round * (round-1)/2;
leftCandies -= ans[i];
}
//最后一轮分配,按照剩余的糖果数分配
int allotCandies = 1 + round * num_people;
//System.out.println(leftCandies + ", allot=" + allotCandies);
for (int i =0; i < num_people; ++i) {
if (allotCandies <= leftCandies) {
ans[i] += allotCandies;
leftCandies -= allotCandies;
allotCandies++;
} else {
ans[i] += leftCandies;
break;
}
}
return ans;
}
}