[LeetCode] Rabbits in Forest 森林里的兔子
In a forest, each rabbit has some color. Some subset of rabbits (possibly all of them) tell you how many other rabbits have the same color as them. Those answers are placed in an array.
Return the minimum number of rabbits that could be in the forest.
Examples:
Input: answers = [1, 1, 2]
Output: 5
Explanation:
The two rabbits that answered "1" could both be the same color, say red.
The rabbit than answered "2" can't be red or the answers would be inconsistent.
Say the rabbit that answered "2" was blue.
Then there should be 2 other blue rabbits in the forest that didn't answer into the array.
The smallest possible number of rabbits in the forest is therefore 5: 3 that answered plus 2 that didn't. Input: answers = [10, 10, 10]
Output: 11 Input: answers = []
Output: 0
Note:
answerswill have length at most1000.- Each
answers[i]will be an integer in the range[0, 999].
这道题说的是大森林中有一堆成了精的兔子,有着不同的颜色,还会回答问题。每个兔子会告诉你森林中还有多少个和其颜色相同的兔子,当然并不是所有的兔子多出现在数组中,所以我们要根据兔子们的回答,来估计森林中最少有多少只能确定的兔子。例子1给的数字是 [1, 1, 2],第一只兔子说森林里还有另一只兔子跟其颜色一样,第二只兔子也说还有另一只兔子和其颜色一样,那么为了使兔子总数最少,我们可以让前两只兔子是相同的颜色,可以使其回答不会矛盾。第三只兔子说森林里还有两只兔子和其颜色一样,那么这只兔的颜色就不能和前两只兔子的颜色相同了,否则就会跟前面两只兔子的回答矛盾了,因为根据第三只兔子的描述,森林里共有三只这种颜色的兔子,所有总共可以推断出最少有五只兔子。对于例子2,[10, 10, 10] 来说,这三只兔子都说森林里还有10只跟其颜色相同的兔子,那么这三只兔子颜色可以相同,所以总共有11只兔子。
来看一个比较tricky的例子,[0, 0, 1, 1, 1],前两只兔子都说森林里没有兔子和其颜色相同了,那么这两只兔子就是森林里独一无二的兔子,且颜色并不相同,所以目前已经确定了两只。然后后面三只都说森林里还有一只兔子和其颜色相同,那么这三只兔子就不可能颜色都相同了,但我们可以让两只颜色相同,另外一只颜色不同,那么就是说还有一只兔子并没有在数组中,所以森林中最少有6只兔子。分析完了这几个例子,我们可以发现,如果某个兔子回答的数字是x,那么说明森林里共有x+1个相同颜色的兔子,我们最多允许x+1个兔子同时回答x个,一旦超过了x+1个兔子,那么就得再增加了x+1个新兔子了。所以我们可以使用一个HashMap来建立某种颜色兔子的总个数和在数组中还允许出现的个数之间的映射,然后我们遍历数组中的每个兔子,如果该兔子回答了x个,若该颜色兔子的总个数x+1不在HashMap中,或者映射为0了,我们将这x+1个兔子加入结果res中,然后将其映射值设为x,表示在数组中还允许出现x个也回答x的兔子;否则的话,将映射值自减1即可,参见代码如下:
解法一:
class Solution {
public:
int numRabbits(vector<int>& answers) {
int res = ;
unordered_map<int, int> m;
for (int ans : answers) {
if (!m.count(ans + ) || m[ans + ] == ) {
res += ans + ;
m[ans + ] = ans;
} else {
--m[ans + ];
}
}
return res;
}
};
下面这种方法换了个角度,核心还是当某个兔子回答x的时候,那么数组中最多允许x+1个兔子同时回答x,那么我们统计数组中所有回答x的兔子的数量n:
若 n%(x+1)==0,说明我们此时只需要 n/(x+1) 组个数为x+1的兔子。
若 n%(x+1)!=0,说明我们此时只需要 n/(x+1) + 1 组个数为x+1的兔子。
那么这两种情况可以通过 ceil(n/(x+1)) 来整合,而这个值也等于 (n + x) / (x + 1),参见代码如下:
解法二:
class Solution {
public:
int numRabbits(vector<int>& answers) {
int res = ;
unordered_map<int, int> m;
for (int ans : answers) ++m[ans];
for (auto a : m) {
res += (a.second + a.first) / (a.first + ) * (a.first + );
}
return res;
}
};
下面这种思路也很巧妙,是先统计出不在数组中的兔子的个数,然后再加上回答问题的兔子数。我们使用一个长度为1000的数字代替HashMap,因为题目中限定了最多1000个兔子回答问题,然后我们对于每个回答x的兔子,将 cnt[x] 的值自增1,然后对 x+1 取余,那么余数就是总数为 x+1 的兔子中在数组中出现的个数,所以我们之后用 x+1 减去这个余数,就是不在数组中的兔子的个数。那么你可能会怀疑,当余数为0了,会不会漏掉了兔子啊,答案是不会的,因为我们最终要加上数组中的兔子个数,如果对 x+1 取余为0了,说明这 x+1 个兔子都在数组中出现了,所以我们不会漏掉任何兔子,参见代码如下:
解法三:
class Solution {
public:
int numRabbits(vector<int>& answers) {
int res = ;
vector<int> cnt(, );
for (int ans : answers) cnt[ans] = (cnt[ans] + ) % (ans + );
for (int i = ; i < ; ++i) {
if (cnt[i] != ) res += i + - cnt[i];
}
return res + answers.size();
}
};
参考资料:
https://leetcode.com/problems/rabbits-in-forest/solution/
https://leetcode.com/problems/rabbits-in-forest/discuss/123206/Java-4-Liner-No-HashMap
https://leetcode.com/problems/rabbits-in-forest/discuss/114719/My-easy-Java-HashMap-solution
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Rabbits in Forest 森林里的兔子的更多相关文章
- LC 781. Rabbits in Forest
In a forest, each rabbit has some color. Some subset of rabbits (possibly all of them) tell you how ...
- LeetCode 781. Rabbits in Forest (森林中的兔子)
题目标签:HashMap 题目给了我们一组数字,每一个数字代表着这只兔子说 有多少只一样颜色的兔子. 我们把每一个数字和它出现的次数都存入map.然后遍历map,来判断到底有多少个一样颜色的group ...
- [Swift]LeetCode781. 森林中的兔子 | Rabbits in Forest
In a forest, each rabbit has some color. Some subset of rabbits (possibly all of them) tell you how ...
- 【LeetCode】781. Rabbits in Forest 解题报告(Python & C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...
- LeetCode解题报告汇总! All in One!
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 把自己刷过的所有题目做一个整理,并且用简洁的语言概括了一下思路,汇总成了一个表格. 题目 ...
- Swift LeetCode 目录 | Catalog
请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift 说明:题目中含有$符号则为付费题目. 如 ...
- leetcode 学习心得 (4)
645. Set Mismatch The set S originally contains numbers from 1 to n. But unfortunately, due to the d ...
- 【LeetCode】数学(共106题)
[2]Add Two Numbers (2018年12月23日,review) 链表的高精度加法. 题解:链表专题:https://www.cnblogs.com/zhangwanying/p/979 ...
- LeetCode All in One题解汇总(持续更新中...)
突然很想刷刷题,LeetCode是一个不错的选择,忽略了输入输出,更好的突出了算法,省去了不少时间. dalao们发现了任何错误,或是代码无法通过,或是有更好的解法,或是有任何疑问和建议的话,可以在对 ...
随机推荐
- JS异步加载的三种方案
js加载的缺点:加载工具方法没必要阻塞文档,个别js加载会影响页面效率,一旦网速不好,那么整个网站将等待js加载而不进行后续渲染等工作. 有些工具方法需要按需加载,用到再加载,不用不加载. 一.def ...
- freemarker和thymeleaf的使用样例
最近需要对公司项目首页使用Java模板重做,以提高首屏加载速度和优化SEO. 在选择模板时发现freemarker和thymeleaf最为常用. 两者最大的区别在于语法,对性能方面未作测试,具体性能测 ...
- JavaScript null和undefined的区别
前言 1995年javascript诞生时,最初像Java一样,只设置了null作为表示"无"的值.根据C语言的传统,null被设计成可以自动转为0 但是,javascript的设 ...
- Kaldi nnet3的前向计算
根据任务,构建ComputationRequst 编译ComputationRequst,获取NnetComputation std::shared_ptr<const NnetComputat ...
- 【汇总目录】C#
[2019年04月29日] C# textbox 自动滚动 [2019年02月07日] C#利用VUDP.cs开发网络通讯应用程序 [2019年02月06日] C#利用VINI.cs操作INI文件 [ ...
- 使用Notepad++开发Java程序
安装NppExec插件(已安装可跳过) 插件下载地址 我选择了最新的RC2 根据软件位数下载对应的版本,我直接下载了32位对应的dll 解压后里面有两个文件夹和一个dll文件 拷贝到Notepad++ ...
- 在badboy中添加检查点并且参数化
在badboy中添加检查点(使用百度搜索来举例): 1.打开badboy,在输入框中输入www.baidu.com,单击键盘回车键或者点击输入框右边的按钮进入百度页面: 2.在百度搜索框中输入搜索字, ...
- windows下使用git和github建立远程仓库
转自(http://www.bubuko.com/infodetail-430228.html) 从昨天开始就在看git的使用,因为在Windows下很多命令行操作都比较坑爹,但是今天再走了无数弯路之 ...
- css-块级格式上下文
定义: 块级格式上下文(Block Formatting Context)是CSS中一个相对冷门的概念,今天被问到才引起注意,下文简单介绍下它的用法,学习资料多来源于网络,实际开发中遇到再继续更博 ...
- Python-Django 模型层-单表查询
单表操作 -增加,删,改:两种方式:queryset对象的方法,book对象的方法 -改:需要用save() -get()方法:查询的数据有且只有一条,如果多,少,都抛异常 单表查询 -<1&g ...