问题描述
给定一个偶数长度的数组,其中不同的数字代表不同种类的糖果。你需要将这些糖果平均分给两个人(例如弟弟和妹妹)。返回其中一人可以获得的最大糖果种类数。
示例 1: 输入:candies = [1,1,2,2,3,3] 输出:3 解析:一共有三种糖果,每种两个。最优分配是每人各拿一种,即 [1,2,3] 和 [1,2,3],此时种类数达到最大。
示例 2: 输入:candies = [1,1,2,3] 输出:2 解析:总共有 4 颗糖,每人分 2 颗。虽然共有 3 种糖果,但受限于每人只能拿 2 颗,最多只能拿到 2 种。
注意:数组长度在 [2, 10000] 之间且为偶数,数值范围在 [-100000, 100000]。
解题思路
这道题的核心其实不在于复杂的博弈策略,而在于理解约束条件。
假设总共有 n 个糖果,平均分给两人,每人必须得到 n / 2 块。那么,无论糖果种类多么丰富,一个人能拿到的最大种类数也不可能超过他手中的糖果总数,也就是 n / 2。
另一方面,如果糖果的总种类数本身就少于 n / 2,那么即使他想拿所有种类,也只能拿到这么多。
因此,问题的解法非常直观:
- 统计数组中不同糖果的种类数(记为 unique_count)。
- 计算每人可分配的糖果数量(记为 limit = n / 2)。
- 最终结果就是两者中的较小值:min(unique_count, limit)。
为什么不需要考虑'避免两人种类相同'这种博弈?因为题目只要求最大化其中一人的种类数。只要把尽可能多的不同种类优先分配给这个人,剩下的自然归另一个人即可。这是一种贪心策略,而非复杂的对抗博弈。
代码实现
利用哈希集合(HashSet)的特性可以高效地统计去重后的种类数。以下是 Java 语言的实现方案:
class Solution {
public int distributeCandies(int[] candies) {
// 使用 HashSet 自动去重,统计糖果种类
Set<Integer> distinctCandies = new HashSet<>();
for (int candy : candies) {
distinctCandies.add(candy);
}
// 获取种类总数
int uniqueCount = distinctCandies.size();
// 每个人能拿到的糖果上限
int limit = candies.length / 2;
// 返回种类数和上限中的较小值
return Math.min(uniqueCount, limit);
}
}
这段代码逻辑清晰,时间复杂度主要取决于遍历数组和哈希表的插入操作,整体效率较高,能够轻松应对题目给定的数据规模。


