Distribute Candies: Sets, Limits, and One Line of Insight
LeetCode 575, Distribute Candies, asks you to figure out the maximum number of different candy types Alice can eat, given that she can only eat half of the total candies.
This is one of those problems where the code is short but the reasoning behind it is worth understanding clearly. The entire solution boils down to one insight: Alice wants variety, but she has a hard limit on quantity.
The problem
Given an integer array candyType of even length n, where each element represents a type of candy, Alice can eat at most n / 2 candies. Return the maximum number of different types she can eat.
candyType = [1, 1, 2, 2, 3, 3]returns3. There are 3 unique types and Alice can eat 3 candies, so she picks one of each.candyType = [1, 1, 2, 3]returns2. There are 3 unique types but Alice can only eat 2 candies. She picks 2 different types.candyType = [6, 6, 6, 6]returns1. There is only 1 unique type. Even though Alice can eat 2 candies, she can only get 1 distinct type.
The approach
Alice wants to maximize the number of different types she eats. She is greedy for variety: given a choice, she will always pick a type she has not eaten yet. The constraint is that she can eat at most n / 2 candies total.
Two things limit her variety:
- The number of unique types. She cannot eat more distinct types than actually exist.
- The eating limit
n / 2. She cannot eat more candies than her quota allows.
The answer is simply the smaller of these two values: min(unique_types, n // 2).
Why does this work? If there are more unique types than her limit, she picks one of each until she hits her quota. If there are fewer unique types than her limit, she eats one of every type and fills the rest with duplicates.
This is a common pattern in greedy problems: identify the two constraints that bound your answer, then return whichever is tighter. No sorting, no dynamic programming, just counting and comparing.
The solution
def distributeCandies(candyType):
unique_types = len(set(candyType))
limit = len(candyType) // 2
return min(unique_types, limit)
Let's walk through the logic:
- Build a set from
candyType. The set automatically removes duplicates, so its size is the number of unique types. - Compute the eating limit as
n // 2. - Return the minimum of the two values. Alice gets as much variety as possible within her quota.
That is the entire solution. Three lines.
Step-by-step walkthrough
Let's trace through candyType = [1, 1, 2, 2, 3, 3]. The array has 6 elements, so Alice can eat 3 candies.
Step 1: Determine the eating limit. n = 6, so Alice can eat n / 2 = 3 candies.
Before looking at types, we know Alice is capped at 3 candies no matter what.
Step 2: Build a set from candyType to find unique types.
Inserting all elements into a set removes duplicates. We find 3 unique types: {1, 2, 3}.
Step 3: Compare unique count to the eating limit.
unique types = 3, eating limit = 3. Since 3 is not greater than 3, Alice can eat all unique types.
Step 4: Return min(unique types, n / 2) = min(3, 3) = 3.
Alice picks types 1, 2, and 3, maximizing the number of different types she eats.
The set {1, 2, 3} has 3 elements. The eating limit is 3. Since min(3, 3) = 3, Alice eats 3 different types.
Complexity analysis
Time: O(n) where n is the length of candyType. Building a set from the array takes one pass through all elements. Each insertion into the set is O(1) on average.
Space: O(n). The set can hold up to n elements in the worst case (when every candy is a different type).
| Approach | Time | Space |
|---|---|---|
| Sort and count unique | O(n log n) | O(1) |
| Set and min | O(n) | O(n) |
The set-based approach trades a bit of space for a better time complexity. Since the problem only asks for the count (not which types to pick), the set approach is the natural fit.
The building blocks
This problem decomposes into two reusable pieces that CodeBricks drills independently:
1. Using a set to count unique elements
The core operation here is converting a collection into a set to eliminate duplicates. This is the same technique you use in Contains Duplicate, Find All Numbers Disappeared in an Array, and any problem where you need to know "how many distinct values exist."
unique_types = len(set(candyType))
The set does all the heavy lifting. You do not need to sort, you do not need to iterate with a counter. One line, O(n) time.
2. Applying a greedy bound
Once you know the number of unique types, the answer is capped by a second constraint (the eating limit). This "take the minimum of two upper bounds" pattern shows up across many greedy problems. You identify the two things that could limit your answer, compute both, and return the smaller one.
return min(unique_types, limit)
This same logic appears in problems like Assign Cookies, where you match supply against demand and take the tighter bound.
Edge cases
Before submitting, verify your solution handles:
- All candies the same type:
[4, 4, 4, 4]. Only 1 unique type exists. Alice eats 2 candies but can only get 1 distinct type. Answer: 1. - All candies different:
[1, 2, 3, 4]. 4 unique types, limit is 2. Alice picks her favorite 2. Answer: 2. - Minimum input:
[1, 2]. 2 unique types, limit is 1. Answer: 1. - Unique types equal the limit:
[1, 1, 2, 2, 3, 3]. 3 unique types, limit is 3. Answer: 3. This is the balanced case where both constraints align.
The set-plus-min solution handles all of these without any special casing.
From understanding to recall
Reading through this solution is one thing. Writing it confidently from a blank editor in an interview is another. The gap between "I understand it" and "I can reproduce it" is where most people lose points on easy problems. Spaced repetition closes that gap: you revisit the set-for-uniqueness and greedy-bound building blocks at increasing intervals, writing the code each time, until identifying these patterns becomes automatic rather than something you have to reason through.
Related posts
- Contains Duplicate - Using a set to detect duplicates, the same core idea of tracking uniqueness
- Find All Numbers Disappeared in an Array - Another array problem that uses a set-based approach to track what exists
- Intersection of Two Arrays - Set operations on arrays, a close relative of counting unique elements
Each of these problems builds on the same foundation: using a set to answer questions about uniqueness in an array. Once that pattern clicks here, the others follow naturally.