【100题】第三十八 (天平称重、大输入流、去除重复URL)
一,题目
1.用天平(只能比较,不能称重)从一堆小球中找出其中唯一一个较轻的。使用x次天平,最多可以从y个小球中找出较轻的那个,求y与x的关系式
2.有一个很大很大的输入流,大到没有存储器可以将其存储下来,而且只输入一次,如何从这个输入流中随机取得m个记录
3.大量的URL字符串,如何从中去除重复的,优化时间空间复杂度
二,分析
1. y=3^x
2. 每次输入一个记录时,随机产生一个0到1之间的随机数,用这些随机数维护一个大小为m的堆。
3. 采用取模hash函数,找一个hash函数了,映射过去,采用链接法避免冲撞 ,如果A映射后的值A!=B,C,D...,把A加入链表,若相同,删除A,继续遍历
三,重点解析第一题
单元测试:三个球A B C,称重A B,A=B--> C为轻;A>B--->B为轻;A<B--->A为轻
所以y取最大值,即每次刚好可以分三份。
第一次 y/3
第二次 (y/3)/3
*
*
第x次 y/(3^x)=1
所以y=3^x
以下为网友给出的解答:
每次将球分成三堆,尽可能让三堆球一样多或者让其中一堆多或者少一个。
球数y和沉重次数x的关系是:
y=1 =>x=0;(显然)
y=2 =>x=1;(显然)
y=3 =>x=2;(显然)
如果y>3,也是将球分为三堆,记为A堆、B堆、C堆
if y=3k(k>1)
称重一次,就可以判断瑕疵球在哪堆,从而使得球数降为k个;
if y=3k+1(k>=1)假设C堆多放1球,A堆和B堆进行称重
称重一次,就可以判断瑕疵球在哪堆,
if A == B ,瑕疵球在C堆,从而使得球数降为k+1个;
else 瑕疵球在轻的堆,从而使得球数降为k个;
if y=3k-1(k>=2)假设C堆少放1球,A堆和B堆进行称重
称重一次,就可以判断瑕疵球在哪堆,
if A == B ,瑕疵球在C堆,从而使得球数降为k个;
else 瑕疵球在轻的堆,从而使得球数降为k-1个;
利用以上过程反复,可得结果。
最后的次数x =log3(y),可能在y哪里还需要做点什么修正。但复杂度就是log
y