Medium
题目描述
森林里有未知数量的兔子。我们询问了 n 只兔子"有多少只其他兔子和你颜色相同?",并将答案收集在整数数组 answers 中,其中 answers[i] 是第 i 只兔子的答案。
给定数组 answers,返回森林中兔子的最少数量。
示例 1:
输入:answers = [1,1,2]
输出:5
解释:
回答 "1" 的两只兔子可能有相同的颜色,比如红色。
回答 "2" 的兔子不能是红色,否则他们的答案就不一致了。
设回答 "2" 的兔子为蓝色。
那么森林中应该有另外 2 只蓝色兔子没有回答问题。
因此森林中兔子的最少数量是 5:3 只回答问题的 + 2 只没有回答问题的。
示例 2:
输入:answers = [10,10,10]
输出:11
提示:
1 <= answers.length <= 10000 <= answers[i] < 1000
解题思路
解题思路
这道题的关键在于理解题目的逻辑:如果一只兔子回答"x",说明包括它自己在内,同颜色的兔子总数是 x+1 只。
贪心策略分析:
为了使兔子总数最少,我们应该尽可能让相同答案的兔子属于同一颜色。具体来说:
- 如果有 count 只兔子都回答"x",那么每 (x+1) 只可以组成一个颜色组
- 需要的颜色组数量为 ⌈count/(x+1)⌉,即 (count + x) / (x + 1)
- 每个颜色组包含 (x+1) 只兔子
算法步骤:
- 统计每个答案出现的次数
- 对于答案为 x 且出现 count 次的情况:
- 需要 ⌈count/(x+1)⌉ 个颜色组
- 每组有 (x+1) 只兔子
- 总贡献:⌈count/(x+1)⌉ × (x+1)
- 将所有答案的贡献相加
这种贪心策略是最优的,因为我们最大化了同色兔子的复用。
代码实现
class Solution {
public:
int numRabbits(vector<int>& answers) {
unordered_map<int, int> count;
for (int answer : answers) {
count[answer]++;
}
int result = 0;
for (auto& [answer, cnt] : count) {
int groupSize = answer + 1;
int groups = (cnt + groupSize - 1) / groupSize;
result += groups * groupSize;
}
return result;
}
};
class Solution:
def numRabbits(self, answers: List[int]) -> int:
from collections import Counter
count = Counter(answers)
result = 0
for answer, cnt in count.items():
group_size = answer + 1
groups = (cnt + group_size - 1) // group_size
result += groups * group_size
return result
public class Solution {
public int NumRabbits(int[] answers) {
var count = new Dictionary<int, int>();
foreach (int answer in answers) {
count[answer] = count.GetValueOrDefault(answer, 0) + 1;
}
int result = 0;
foreach (var kvp in count) {
int answer = kvp.Key;
int cnt = kvp.Value;
int groupSize = answer + 1;
int groups = (cnt + groupSize - 1) / groupSize;
result += groups * groupSize;
}
return result;
}
}
var numRabbits = function(answers) {
const count = new Map();
for (const answer of answers) {
count.set(answer, (count.get(answer) || 0) + 1);
}
let result = 0;
for (const [answer, cnt] of count) {
const groupSize = answer + 1;
const groups = Math.ceil(cnt / groupSize);
result += groups * groupSize;
}
return result;
};
复杂度分析
| 复杂度类型 | 复杂度 |
|---|---|
| 时间复杂度 | O(n) |
| 空间复杂度 | O(k) |
其中 n 是 answers 数组的长度,k 是不同答案的数量(最多为 1001)。