题目描述
森林中,每个兔子都有颜色。其中一些兔子(可能是全部)告诉你还有多少其他的兔子和自己有相同的颜色。我们将这些回答放在 answers
数组里。
返回森林中兔子的最少数量。
样例
输入:answers = [1, 1, 2]
输出:5
解释:
两只回答了 "1" 的兔子可能有相同的颜色,设为红色。
之后回答了 "2" 的兔子不会是红色,否则他们的回答会相互矛盾。
设回答了 "2" 的兔子为蓝色。
此外,森林中还应有另外 2 只蓝色兔子的回答没有包含在数组中。
因此森林中兔子的最少数量是 5,有 3 只回答的和 2 只没有回答的。
输入:answers = [10, 10, 10]
输出:11
输入:answers = []
输出:0
限制
answers
的长度最大为1000
。answers[i]
是在[0, 999]
范围内的整数。
算法
(哈希表,数学) O(n)
- 用哈希表统计每种数字出现的次数。
- 不同数字之间的颜色一定是不同的,且每种颜色的兔子一定是
x + 1
的整数倍。 - 设某个数字
x
的出现次数为num
- 如果
num
是x + 1
的整数倍,则恰好需要有num / (x + 1)
种颜色,且这num
只兔子都回答了。 - 否则,需要
num / (x + 1) + 1
种颜色,共有(num / (x + 1) + 1) * (x + 1)
只兔子回答了x
。
- 如果
时间复杂度
- 遍历整个回答存入哈希表,然后分析每个回答,故总时间复杂度为 O(n)。
空间复杂度
- 需要 O(n) 的额外空间存储哈希表。
C++ 代码
class Solution {
public:
int numRabbits(vector<int>& answers) {
unordered_map<int, int> seen;
for (int x : answers)
seen[x]++;
int tot = 0;
for (const auto &it : seen) {
int x = it.first, num = it.second;
if (num % (x + 1) == 0) tot += num;
else tot += (num / (x + 1) + 1) * (x + 1);
}
return tot;
}
};
每次AC后都不敢看题解,因为一看题解就知道我有多笨。。