math
simulation
]
Leetcode 1103. Distribute Candies to People
https://leetcode.com/problems/distribute-candies-to-people
There are different ways how you can handle this problem, I prefer mathematical way. Let us define k = num_people and n = candies and try to understand how many candies we need to give to i-the person.
| 1 | 2 | 3 | … | k |
|---|---|---|---|---|
| k+1 | k+2 | k+3 | … | 2k |
| … | … | … | … | … |
| sk+1 | … | sk+i |
We need to find the biggest s, such that the sum of numbers before is less or equal to n. Let us compute it:
1. First row: k(k+1)/2, sum of arithmetic progression.
2. Second row: k(k+1)/2 + k^2.
3. Third row: k(k+1)/2 + 2*k^2.
…
s-1. k(k+1)/2 + (s-1)*k^2.
s. s*k*i + i(i+1)/2.
Let us evaluate this sum and solve quadratic inequality:

So, we have root s = ((-1-2*i) + sqrt(1+8*n))/(2*k) and we need to find the biggest integer number which is less than s, let us define it t = floor(s).
Now, how many candies we need to give to this person? It is i + (k+i) + ... + (sk+i) = i*(t+1) + k*t*(t+1)//2. Finally, we need to find the last person, who gets the rest of the candies. How we can do it? I evaluate difference s - floor(s) and choose the person with the biggest difference.
Complexity: time and space complexity is O(k), where k is number of people.
class Solution:
def distributeCandies(self, candies, num_people):
k, n = num_people, candies
alloc = [0]*k
Final = (0, 0)
for i in range(1, k+1):
s = ((-1-2*i) + sqrt(1+8*n))/(2*k)
t = floor(s)
alloc[i-1] = i*(t+1) + k*t*(t+1)//2
Final = max(Final, (s-floor(s), i))
alloc[Final[1]-1] += (n - sum(alloc))
return alloc
If you like the solution, you can upvote it on leetcode discussion section: Problem 1103