题目链接 : Lc 781. 森林中的兔子
思路分析
-
题目要求的是森林中最少的兔子数量, 那么最少兔子数量的情况就是根据兔子的回答将它们尽量分到同一组中去, 即例子中 1, 1, 2, 第一只兔子表明和自己相同颜色的兔子还有一只,第二只兔子回答也是表明和自己颜色相同的兔子还有一只,此时我们就可以将第一只兔子和第二只兔子归为同一类, 第三只兔子表明和自己颜色相同的兔子还有2只,此时就排除了第一只,第二只,第三只是同一类的可能性,故第三只兔子单独成一类,且这一类中兔子的个数为 2 + 1 = 3; 故这种情况的兔子的最少数量为2 + 3 = 5
-
即通过上面的分析我们就知道了,回答相同的兔子我们可以将它们归为一类,但并不是所有回答相同的兔子我们都能把它归为一类,例如第一只兔子回答 x, 这就表明了这只兔子所处的类中兔子的个数为 x + 1, 如果回答x 的个数超过了 x + 1, 则超过部分的应该又是单独一组。例如当兔子回答 1 , 1, 1这种情况,我们通过上面的分析可以知道,我们可以将第一只和第二只兔子归为同一组, 但第三只兔子回答1的时候,此时前面的一类最多只有两只,而第一只和第二只已经被划分为同一组中去了,故第三只单独成另一类,且这类的个数为2,故这种情况下兔子的最少数量为 2 + 2 = 4;
-
通过上面的分析我们已经知道了大概的一个思路,即我们可以统计一下所有回答的数量,例如我们记录到回答x 的 兔子个数是 n, 我们可以知道回答x的兔子所处的类的最兔子总数为 x + 1, 即当 n < x. 那么这类兔子的数量就是 x + 1, 若超过则说明又是另一类的兔子,且这类兔子的总数也为 x + 1, 故我们可以
C++代码实现
class Solution
{
public:
int numRabbits(vector<int>& answers)
{
unordered_map<int, int> m;
for(auto x : answers) m[x]++;
int res = 0;
for(auto [k, v] : m)
res += (v + k + 1 - 1) / (k + 1) * (k + 1);
return res;
}
};
代码分析
这里我们是用哈希表存储每个回答出现的次数, 最后用range_for进行哈希表的遍历, k即为每只兔子的回答的答案, v 为 回答这个答案的兔子个数, 故我们得知回答x的兔子所处的类其兔子总数为 k + 1, 根据上面的分析我们可以得到总数为k + 1的兔子的组数为 v / (k + 1) 上取整, 但C++的整数除法是下取整的,那如何转换 ? 可以用下面公式转换, 这也就是上面的range_for的组数 x (k + 1) 的写法 。