2928. Distribute Candies Among Children I
Problem Description
You have n
candies that need to be distributed among 3 children. Each child can receive between 0 and limit
candies (inclusive). Your task is to find the total number of different ways to distribute all n
candies among the 3 children such that no child receives more than limit
candies.
For example, if you have 5 candies and the limit is 2, you need to count all valid distributions where child 1, child 2, and child 3 each get at most 2 candies, and the sum of candies equals 5.
The problem uses combinatorial mathematics and the inclusion-exclusion principle to solve this. The solution treats this as a "stars and bars" problem where we need to place n
identical items into 3 distinct boxes with capacity constraints.
The formula calculates:
- Start with all possible ways to distribute
n
candies among 3 children without restrictions:C(n+2, 2)
- Subtract cases where at least one child gets more than
limit
candies:3 * C(n-limit+1, 2)
- Add back cases where at least two children get more than
limit
candies (since they were subtracted twice):3 * C(n-2*limit, 2)
The function returns 0 if n > 3 * limit
since it's impossible to distribute the candies within the constraints.
Intuition
The key insight is recognizing this as a classic "stars and bars" combinatorial problem with upper bound constraints.
First, let's think about the simpler version without any limits. If we just want to distribute n
identical candies among 3 children, we can visualize this as arranging n
stars and 2 bars, where bars separate the candies for each child. For example, **|*|***
means child 1 gets 2, child 2 gets 1, and child 3 gets 3 candies. The number of ways to arrange these is C(n+2, 2)
.
Why C(n+2, 2)
? We have n
candies and need 2 dividers to create 3 groups. We're choosing 2 positions for dividers among n+2
total positions.
Now comes the tricky part - we have an upper limit. Some of our distributions give a child more than limit
candies, which violates our constraint. We need to remove these invalid cases.
Using the inclusion-exclusion principle:
- First, count all distributions (including invalid ones)
- Then subtract distributions where at least one child exceeds the limit
- But wait! When we subtract cases where "child 1 exceeds" and separately subtract "child 2 exceeds", we've double-subtracted cases where both children exceed the limit
- So we need to add those back
If one child must get more than limit
candies (at least limit+1
), we can "pre-allocate" limit+1
candies to that child, leaving n-(limit+1)
candies to distribute freely. This gives us C(n-limit+1, 2)
ways. Since any of the 3 children could be the one exceeding, we multiply by 3.
Similarly, for cases where two children both exceed the limit, we pre-allocate 2*(limit+1)
candies and distribute the remaining n-2*limit-2
candies, giving us C(n-2*limit, 2)
ways for each pair of children.
Learn more about Math and Combinatorics patterns.
Solution Approach
The implementation uses the inclusion-exclusion principle with combinatorial mathematics to count valid distributions.
Step 1: Check Impossible Case
if n > 3 * limit: return 0
If we have more candies than the maximum possible distribution (3 children × limit candies each), it's impossible to distribute them within constraints.
Step 2: Count All Possible Distributions Without Constraints
ans = comb(n + 2, 2)
Using the stars and bars method, we count all ways to distribute n
candies among 3 children. This is equivalent to choosing 2 positions for dividers among n + 2
total positions, giving us C(n+2, 2)
combinations.
Step 3: Subtract Invalid Cases (At Least One Child Exceeds Limit)
if n > limit: ans -= 3 * comb(n - limit + 1, 2)
When at least one child gets more than limit
candies:
- We "fix"
limit + 1
candies to one child (the minimum to exceed) - Distribute the remaining
n - (limit + 1) = n - limit - 1
candies among all 3 children - This gives
C(n - limit - 1 + 2, 2) = C(n - limit + 1, 2)
ways - Since any of the 3 children could be the one exceeding, multiply by 3
Step 4: Add Back Over-Subtracted Cases (At Least Two Children Exceed Limit)
if n - 2 >= 2 * limit: ans += 3 * comb(n - 2 * limit, 2)
In Step 3, we double-counted cases where two children both exceed the limit:
- Fix
2 * (limit + 1)
candies to two children - Distribute the remaining
n - 2 * (limit + 1) = n - 2 * limit - 2
candies - This gives
C(n - 2 * limit - 2 + 2, 2) = C(n - 2 * limit, 2)
ways - There are 3 ways to choose which 2 children exceed the limit
Note: Cases where all 3 children exceed the limit are impossible since that would require n > 3 * limit
, which we already handled in Step 1.
The final answer is the result after applying all inclusion-exclusion adjustments.
Ready to land your dream job?
Unlock your dream job with a 5-minute evaluator for a personalized learning plan!
Start EvaluatorExample Walkthrough
Let's walk through a concrete example: n = 5 candies, limit = 2
We need to find all ways to distribute 5 candies among 3 children where each child gets at most 2 candies.
Step 1: Check if distribution is possible
- Maximum possible candies = 3 × 2 = 6
- Since 5 ≤ 6, distribution is possible ✓
Step 2: Count all distributions without constraints Using stars and bars: C(5+2, 2) = C(7, 2) = 21
This counts arrangements like:
- (5, 0, 0) - child 1 gets 5 candies ❌ exceeds limit
- (3, 1, 1) - child 1 gets 3 candies ❌ exceeds limit
- (2, 2, 1) - valid ✓
- (2, 1, 2) - valid ✓
- (1, 2, 2) - valid ✓
Step 3: Subtract cases where at least one child exceeds limit (gets > 2) A child exceeding means getting at least 3 candies.
- Fix 3 candies to one child, distribute remaining 5-3=2 candies
- Ways to distribute 2 candies among 3 children: C(2+2, 2) = C(4, 2) = 6
- Any of 3 children could exceed: 3 × 6 = 18
These 18 cases include distributions like:
- Child 1 exceeds: (3,2,0), (3,1,1), (3,0,2), (4,1,0), (4,0,1), (5,0,0)
- Child 2 exceeds: (2,3,0), (1,3,1), (0,3,2), (1,4,0), (0,4,1), (0,5,0)
- Child 3 exceeds: (2,0,3), (1,1,3), (0,2,3), (1,0,4), (0,1,4), (0,0,5)
Step 4: Add back cases where at least two children exceed limit Two children exceeding means each gets at least 3 candies = 6 total minimum. Since 5 < 6, it's impossible for two children to both exceed the limit.
- Check: 5 - 2 = 3, and 3 < 2×2 = 4, so this step contributes 0
Final Answer: 21 - 18 + 0 = 3
The 3 valid distributions are:
- (2, 2, 1) - child 1 gets 2, child 2 gets 2, child 3 gets 1
- (2, 1, 2) - child 1 gets 2, child 2 gets 1, child 3 gets 2
- (1, 2, 2) - child 1 gets 1, child 2 gets 2, child 3 gets 2
Each distribution sums to 5 and no child gets more than 2 candies ✓
Solution Implementation
1from math import comb
2
3class Solution:
4 def distributeCandies(self, n: int, limit: int) -> int:
5 """
6 Calculate the number of ways to distribute n candies among 3 children
7 where each child can receive at most 'limit' candies.
8
9 Uses inclusion-exclusion principle to count valid distributions.
10
11 Args:
12 n: Total number of candies to distribute
13 limit: Maximum number of candies each child can receive
14
15 Returns:
16 Number of valid ways to distribute the candies
17 """
18 # If total candies exceed maximum possible distribution (3 children * limit each)
19 # then it's impossible to distribute
20 if n > 3 * limit:
21 return 0
22
23 # Start with total ways to distribute n candies among 3 children
24 # without any limit (stars and bars formula: C(n+2, 2))
25 total_ways = comb(n + 2, 2)
26
27 # Subtract distributions where at least one child gets more than limit
28 # Each child getting > limit candies contributes C(n-limit+1, 2) invalid ways
29 # There are 3 such cases (one for each child)
30 if n > limit:
31 total_ways -= 3 * comb(n - limit + 1, 2)
32
33 # Add back distributions where at least two children get more than limit
34 # (inclusion-exclusion principle correction for overcounting)
35 # This happens when remaining candies after giving 2*limit can still be distributed
36 if n - 2 >= 2 * limit:
37 total_ways += 3 * comb(n - 2 * limit, 2)
38
39 return total_ways
40
1class Solution {
2 /**
3 * Distributes n candies among 3 children where each child can receive at most 'limit' candies.
4 * Uses inclusion-exclusion principle to count valid distributions.
5 *
6 * @param n Total number of candies to distribute
7 * @param limit Maximum number of candies each child can receive
8 * @return Number of ways to distribute the candies
9 */
10 public int distributeCandies(int n, int limit) {
11 // If total candies exceed maximum possible distribution (3 children * limit each)
12 if (n > 3 * limit) {
13 return 0;
14 }
15
16 // Start with total ways to distribute n candies among 3 children without limit
17 // This is equivalent to choosing 2 positions for dividers among (n+2) positions
18 long totalWays = calculateCombination2(n + 2);
19
20 // Subtract invalid cases where at least one child gets more than limit candies
21 // Using inclusion-exclusion: subtract cases where 1 child exceeds limit
22 if (n > limit) {
23 // If one child gets (limit + 1) or more candies,
24 // we have (n - limit - 1) candies left to distribute freely
25 totalWays -= 3 * calculateCombination2(n - limit + 1);
26 }
27
28 // Add back cases where at least two children exceed limit (overcounted above)
29 // This corrects the inclusion-exclusion calculation
30 if (n - 2 >= 2 * limit) {
31 // If two children each get (limit + 1) or more candies,
32 // we have (n - 2*limit - 2) candies left to distribute freely
33 totalWays += 3 * calculateCombination2(n - 2 * limit);
34 }
35
36 return (int) totalWays;
37 }
38
39 /**
40 * Calculates C(n, 2) = n choose 2 = n * (n-1) / 2
41 * Represents the number of ways to choose 2 items from n items
42 *
43 * @param n Number of items to choose from
44 * @return The binomial coefficient C(n, 2)
45 */
46 private long calculateCombination2(int n) {
47 return 1L * n * (n - 1) / 2;
48 }
49}
50
1class Solution {
2public:
3 int distributeCandies(int n, int limit) {
4 // Lambda function to calculate C(n, 2) = n choose 2 = n * (n-1) / 2
5 // This represents the number of ways to choose 2 items from n items
6 auto calculateCombination2 = [](int n) -> long long {
7 return static_cast<long long>(n) * (n - 1) / 2;
8 };
9
10 // If total candies exceed the maximum possible distribution (3 children * limit each)
11 // then it's impossible to distribute
12 if (n > 3 * limit) {
13 return 0;
14 }
15
16 // Start with total unrestricted distributions using stars and bars formula
17 // C(n + 3 - 1, 3 - 1) = C(n + 2, 2) for distributing n items to 3 children
18 long long totalWays = calculateCombination2(n + 2);
19
20 // Apply inclusion-exclusion principle
21 // Subtract cases where at least one child gets more than limit candies
22 if (n > limit) {
23 // For each child that could exceed the limit, subtract invalid distributions
24 // If one child gets (limit + 1) or more, we have (n - limit - 1) candies left
25 // to distribute among 3 children: C(n - limit - 1 + 2, 2)
26 totalWays -= 3 * calculateCombination2(n - limit + 1);
27 }
28
29 // Add back cases where at least two children exceed the limit (overcounted above)
30 if (n - 2 * limit - 2 >= 0) {
31 // If two children each get (limit + 1) or more candies
32 // We have (n - 2 * (limit + 1)) = (n - 2 * limit - 2) candies left
33 // Simplified: n - 2 >= 2 * limit means n - 2 * limit - 2 >= 0
34 totalWays += 3 * calculateCombination2(n - 2 * limit);
35 }
36
37 return static_cast<int>(totalWays);
38 }
39};
40
1/**
2 * Calculates the number of ways to distribute n candies among 3 children
3 * where each child can receive at most 'limit' candies.
4 *
5 * @param n - Total number of candies to distribute
6 * @param limit - Maximum number of candies each child can receive
7 * @returns Number of valid distributions
8 */
9function distributeCandies(n: number, limit: number): number {
10 /**
11 * Helper function to calculate combinations C(n, 2) = n * (n - 1) / 2
12 * Represents the number of ways to choose 2 items from n items
13 *
14 * @param n - Total number of items
15 * @returns Number of combinations
16 */
17 const calculateCombinationOfTwo = (n: number): number => {
18 return (n * (n - 1)) / 2;
19 };
20
21 // If total candies exceed the maximum possible (3 children * limit each),
22 // no valid distribution exists
23 if (n > 3 * limit) {
24 return 0;
25 }
26
27 // Start with total unrestricted distributions using stars and bars formula
28 // C(n + 3 - 1, 3 - 1) = C(n + 2, 2)
29 let totalDistributions: number = calculateCombinationOfTwo(n + 2);
30
31 // Apply inclusion-exclusion principle to subtract invalid cases
32 // where at least one child gets more than 'limit' candies
33 if (n > limit) {
34 // Subtract cases where at least one child exceeds the limit
35 // Multiply by 3 for each child that could exceed
36 totalDistributions -= 3 * calculateCombinationOfTwo(n - limit + 1);
37 }
38
39 // Add back cases that were over-subtracted (inclusion-exclusion)
40 // Cases where at least two children exceed the limit
41 if (n - 2 >= 2 * limit) {
42 totalDistributions += 3 * calculateCombinationOfTwo(n - 2 * limit);
43 }
44
45 return totalDistributions;
46}
47
Time and Space Complexity
The time complexity is O(1)
because the algorithm performs a fixed number of operations regardless of the input size. The function only executes:
- A constant number of comparisons (
if
statements) - A fixed number of calls to the
comb
function, where each call computescomb(a, 2)
which equalsa * (a - 1) / 2
and can be calculated in constant time - Basic arithmetic operations (additions, subtractions, multiplications)
Since all operations take constant time and there are no loops or recursive calls that depend on the input size, the overall time complexity is O(1)
.
The space complexity is O(1)
because the algorithm only uses a fixed amount of extra space:
- A single variable
ans
to store the result - Temporary variables for intermediate calculations in the
comb
function calls - No additional data structures that grow with input size
The space usage remains constant regardless of the value of n
or limit
, resulting in O(1)
space complexity.
Learn more about how to find time and space complexity quickly.
Common Pitfalls
1. Incorrect Boundary Check for Adding Back Over-Subtracted Cases
One of the most common mistakes is using the wrong condition to determine when to add back the over-subtracted cases in the inclusion-exclusion principle.
Incorrect Implementation:
if n - 2 >= 2 * limit: # Wrong condition ans += 3 * comb(n - 2 * limit, 2)
Why it's wrong: The condition n - 2 >= 2 * limit
doesn't correctly check whether two children can each receive more than limit
candies. The correct condition should verify if we have enough candies to give limit + 1
to two children.
Correct Implementation:
if n > 2 * limit + 1: # Correct condition ans += 3 * comb(n - 2 * limit - 2, 2)
Explanation: For two children to each exceed the limit, we need at least 2 * (limit + 1) = 2 * limit + 2
candies. So the condition should be n >= 2 * limit + 2
or equivalently n > 2 * limit + 1
.
2. Misunderstanding the Combinatorial Formula
Another pitfall is incorrectly calculating the combinations when applying inclusion-exclusion.
Incorrect Approach:
# Wrong: Using n - limit - 1 instead of n - limit + 1 if n > limit: ans -= 3 * comb(n - limit - 1, 2) # Wrong formula
Correct Approach:
if n > limit: ans -= 3 * comb(n - limit + 1, 2) # Correct formula
Why: When one child gets limit + 1
candies (minimum to exceed), we have n - (limit + 1) = n - limit - 1
candies left to distribute among 3 children. Using stars and bars, this gives us C(n - limit - 1 + 2, 2) = C(n - limit + 1, 2)
.
3. Not Handling Edge Cases Properly
Problem: Forgetting to check if the combination arguments are valid (non-negative).
Example of problematic code:
# This could fail if n - 2 * limit - 2 < 0 ans += 3 * comb(n - 2 * limit - 2, 2)
Solution: Always ensure the first argument to comb()
is non-negative:
if n >= 2 * limit + 2: # Ensure n - 2 * limit - 2 >= 0 ans += 3 * comb(n - 2 * limit - 2, 2)
4. Off-by-One Errors in Limit Calculations
Common Mistake: Confusing "at most limit" with "exactly limit + 1" when calculating invalid cases.
Wrong thinking: "If a child gets more than limit candies, they get at least limit candies" Correct thinking: "If a child gets more than limit candies, they get at least limit + 1 candies"
This subtle difference affects all the formulas in the inclusion-exclusion calculation and can lead to completely incorrect results.
What is the best way of checking if an element exists in an unsorted array once in terms of time complexity? Select the best that applies.
Recommended Readings
Math for Technical Interviews How much math do I need to know for technical interviews The short answer is about high school level math Computer science is often associated with math and some universities even place their computer science department under the math faculty However the reality is that you
Backtracking Template Prereq DFS with States problems dfs_with_states Combinatorial search problems Combinatorial search problems involve finding groupings and assignments of objects that satisfy certain conditions Finding all permutations combinations subsets and solving Sudoku are classic combinatorial problems The time complexity of combinatorial problems often grows rapidly with the size of
Coding Interview Patterns Your Personal Dijkstra's Algorithm to Landing Your Dream Job The goal of AlgoMonster is to help you get a job in the shortest amount of time possible in a data driven way We compiled datasets of tech interview problems and broke them down by patterns This way
Want a Structured Path to Master System Design Too? Don’t Miss This!