LeetCode 575. 分糖果
题目描述
✅ 575. 分糖果


题意分析
从
n颗糖中选出n/2颗,使选到的不同种类最多,题目保证n为偶数。相同种类可以选多颗,但对种类数只贡献一次;类型编号只用来判断是否相同,大小和正负没有其他含义。
解法:去重计数
核心思路
[!blue]
设全部糖果共有
u种,可以选的颗数为limit=n/2。答案不可能超过已有种类数u;每得到一种还至少需要占用一个名额,所以也不能超过limit。因此min(u,limit)是上界。这个上界一定能达到。若
u >= limit,选出limit个不同种类,每种拿一颗即可;若u < limit,先从每种拿一颗,再从剩余糖果中任意补足颗数,仍然保留全部u种。原来共有n颗糖,补足到n/2总有足够的剩余糖果。既然最优值只取决于不同种类的数量,用集合去重即可,无需记录每种具体出现几次,也无需实际构造选择方案。
解题步骤
- 用集合统计不同编号。
- 可选颗数为原数组长度的一半。
- 返回种类数与颗数上限的较小值。
全部糖果同类时答案为
1;所有糖果都不同类时,答案由名额限制为n/2。
代码实现
class Solution {
public int distributeCandies(int[] candyType) {
Set<Integer> set = new HashSet<>();
for (int t : candyType) {
set.add(t);
}
// 不同种类数同时受已有种类与可选颗数限制
return Math.min(set.size(), candyType.length / 2);
}
}
func distributeCandies(candyType []int) int {
set := make(map[int]struct{})
for _, v := range candyType {
set[v] = struct{}{}
}
// 不同种类数同时受已有种类与可选颗数限制
limit := len(candyType) / 2
if len(set) < limit {
return len(set)
}
return limit
}
复杂度分析
- 时间复杂度:期望 $O(n)$,扫描一次并去重。
- 空间复杂度:$O(u)$,其中
u为全部糖果的不同种类数。
关键点总结
[!green]
- 总种类数和可选颗数共同给出上界。
- 两种情况下都能构造达到上界的选择,取较小值才是确切答案。
易错点总结
[!yellow]
- 只返回种类数,会超过可选颗数。
- 只返回一半长度,会高估全相同的情况。
- 用去重后的长度除二,混淆了种类与颗数。
相似题目
| 题目 | 难度 | 关联与区别 |
|---|---|---|
| 2357. 使数组中所有元素都等于零 | 简单 | 同样先识别答案与不同数值种类的关系,本题还受只能拿总数一半的容量限制。 |
转载与许可
许可
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处!