问题描述:有1000桶酒,其中1桶有毒。而一旦吃了,毒性会在1周后发作。现在我们用小老鼠做实验,要在1周后找出那桶毒酒,问最少需要多少老鼠。
答案:老鼠个位为:10只, 2^10 = 1024 > 1000
解题:
(1)把10只老鼠依次排队为:0 - 9,关在笼子里
(2)把1000只桶酒依次编号,并换算成二进制,如 8 = 1000,根据二进制中出现1的位数对相应位置小鼠酒。 因为我们选择的是10只
小鼠,2^10 = 1024 > 1000,能够保证所有的编号的酒都能被喂小鼠而不会遗漏被转为二进制的1的位.
(3)长时间的等待,等待小鼠的死亡
(4)把死亡小鼠的依次记录,如 00001 00010 = 34
分析:我们记得两数进行或“ | ”操作,只要有1结果总是1,就是这个原理,当有毒的酒被编号二进制喂给小鼠,只有被喂食的小鼠都 会死掉,正是死掉的小鼠记录了有毒酒的二进制。记录的结果就是有毒酒的二进制,转化就可以得到其编号。
思考:看到结果后,感觉问题很简单,并且如果有思路,很快就能给出答案,有的给2000桶酒,我们可以很快的给出答案:
2^11 = 1024 * 2 > 2000,就是11只。如果是第一次遇到真不好想,就如在一个字符串中查找某个字符是否出现,有人想的
方案是把26个字符和一个质数对应,把要查找的字符串字母对应质数相乘得出一个结果,只要把此结果除以待查字母的质数
值,整除说明查到了此字母的字符串中的出现(有人会问,这个方案,至少要遍历一遍待匹配字符串,而单个匹配的最坏
时间复杂度才是o(n),但如果要在此字符串中进行多次查找时,质数方案是很不错的方案)。
再次思考:迷迷糊糊中记得,有个面试题是在上亿条记录中查找一个字符串的出现。我们看下面的方案
方案一:把上亿条记录插入到数据库,直接把字符串在数据库中查阅
缺点:占用大量空间,查阅速度慢
方案二:把上亿条记录经hash记录到数据中,带查找字符串也经hash在数据库中做检索
缺点:上亿条记录经hash也是上亿条记录,占用空间
优点:在方案一的基础上由于hash会空间会得到减小
方案三:使用Bloom Filter,只需申请空间为字符串20倍的空间,就能在很低可接受的失败率0.0000 8的条件下,实现字符串的匹配
假设字符串为个数为1亿 1*10^8,则申请20 * 1 * 10^8的bit位大小,选取10个设计好的hash函数散列,把1亿条记录每个做10
次hash散列,记录在申请的bit位上置 1。将待查的字符串进行10次hash散列,得到10次的结果,都能在相应位得到查阅值为
1时,就能认为此串被查到。可参考Bloom Filter相关文章
缺点:10个hash散列函数的选择难度较大
优点:节约大量占用空间,在低冲突及失败的情况下很好的大数据处理
总结:在看到面试题时,适当的思考,依次展开,深入学习,让自己成为好的设计师
把自己的学习记录下来,供自己更深入学习。