You are given two positive integers n
and limit
.
Return the total number of ways to distribute n
candies among 3
children such that no child gets more than limit
candies.
For example:
Input: n = 5
, limit = 2
Output: 3
Explanation: There are 3 ways to distribute 5 candies such that no child gets more than 2 candies: (1, 2, 2)
, (2, 1, 2)
and (2, 2, 1)
.
Input: n = 3
, limit = 3
Output: 10
Explanation: There are 10 ways to distribute 3 candies such that no child gets more than 3 candies: (0, 0, 3)
, (0, 1, 2)
, (0, 2, 1)
, (0, 3, 0)
, (1, 0, 2)
, (1, 1, 1)
, (1, 2, 0)
, (2, 0, 1)
, (2, 1, 0)
and (3, 0, 0)
.
A brute-force solution would involve iterating through all possible combinations of candy distribution among the three children and counting the valid ones (where no child receives more than limit
candies). We can accomplish this using three nested loops. This approach is very inefficient due to its high time complexity.
def count_ways_naive(n: int, limit: int) -> int:
count = 0
for i in range(min(n, limit) + 1):
for j in range(min(n - i, limit) + 1):
k = n - i - j
if k <= limit:
count += 1
return count
Time Complexity: O(n^2), because of the nested loops.
Space Complexity: O(1), as we use only a constant amount of extra space.
A more efficient approach involves using inclusion-exclusion principle to solve this problem.
First, consider there is no limit on the number of candies each child can get. The number of ways to distribute n candies to 3 children without any limit is equivalent to the number of ways to place 2 dividers among n candies, which can be calculated using combinations formula C(n+2, 2) = (n+2)(n+1) / 2
.
Now, we need to subtract the invalid cases, where at least one child gets more than limit
candies. We use inclusion-exclusion principle.
limit
candies. Let's say the first child has more than limit
candies, which means it has at least limit + 1
candies. So, we give limit + 1
candies to the first child, and then distribute the remaining n - limit - 1
candies to the 3 children without any limit. This can be calculated as C(n - limit - 1 + 2, 2) = C(n - limit + 1, 2) = (n - limit + 1)(n - limit) / 2
. Since any of the three children can exceed the limit, we multiply this by 3.limit
candies. In this case, each of these two children has at least limit + 1
candies. So, we give limit + 1
candies to each of these two children, and then distribute the remaining n - 2 * (limit + 1)
candies to the 3 children without any limit. This can be calculated as C(n - 2 * (limit + 1) + 2, 2) = C(n - 2 * limit, 2) = (n - 2 * limit)(n - 2 * limit - 1) / 2
. Since there are 3 ways to choose the two children who exceed the limit, we multiply this by 3.limit
candies. In this case, each of these three children has at least limit + 1
candies. So, we give limit + 1
candies to each of these three children, which means the total candies will be at least 3 * (limit + 1)
. If n is less than 3 * (limit + 1)
, it will be impossible, or else we can calculate C(n - 3 * (limit + 1) + 2, 2) = C(n - 3 * limit - 1, 2) = (n - 3 * limit - 1)(n - 3 * limit - 2) / 2
.Using inclusion-exclusion, we can calculate the total number of ways as follows:
Total Ways = C(n+2, 2) - 3 * C(n - limit + 1, 2) + 3 * C(n - 2 * limit, 2) - C(n - 3 * limit - 1, 2)
def combinations(n: int) -> int:
if n < 0:
return 0
return (n * (n + 1)) // 2
def count_ways_optimal(n: int, limit: int) -> int:
total_ways = combinations(n + 2)
one_exceeds = 3 * combinations(n - limit - 1 + 2 -1)
two_exceeds = 3 * combinations(n - 2 * (limit + 1) + 2 -1)
three_exceeds = combinations(n - 3 * (limit + 1) + 2-1)
result = total_ways - one_exceeds + two_exceeds - three_exceeds
return result
Time Complexity: O(1), as the calculations involve constant-time operations.
Space Complexity: O(1), as we use only a constant amount of extra space.