第一道题 TAOCP 第二卷开头就讲了。 而且讲的是更强的在外存上操作的情形。 我觉得思路不难想, 就是假设某个N终止了,这时候要等概率。 然
后新来一个,又要等概率,必定是要以 1/N+1 概率替换掉原来的。 验证一下的确正确。
On May 9, 12:22 am, "怀宇范" <
dugugu...@gmail.com> wrote:
> 赞过。。。这题昨天翻编程珠玑的时候看过得解。。。但我有一些其他的想法不知对否。。。
>
> 1. 遍历1次,用数组保存下所有链表的脚标,然后random。题目说是遍历一次,小专个空子不知对否?
> 2.
> 还是沿用空间换时间的思路,遍历一次得到一个从C[i]=A[1]*...*A[i-1],再反向遍历一次得到D[i]=A[i+1]*...*A[N],so
> B[i]=C[i]*D[i]。。。另防止越界对边界做1的处理。。。
> 3. 看过就不说了。。。
>
> 2008/5/9 Marshall <
liujinmarsh...@gmail.com>:
>
>
>
> > 第一题其实是编程珠玑习题12.10的推广,原题既是k=1的情况,关键就是想到可以替换以前已经选择的元素。
> > 按照这个思路:
> > 1. 对于前k个,全部选择,即选择集S里为前k个元素
> > 2. 第k+i(i>0)个时,令r1=rand(1,k+i),如果r1>k,则保持现有的选择集合S不变
> > 3. 如果r1<=k, 令r2=rand(1,k),并让第k+i元素(即当前元素)替换集合S里第r2个元素
>
> > 归纳:
> > 1. 如果N=k, 前k个全部选择,被选择概率p=1
> > 2. 如果N=k+1, 第k+1个被选择的概率为p=k/(k+1),前k个被选择的概率为
> > p=1*(1/(k+1)+(k/(k+1))*((k-1)/k)) = k/(k+1)
> > 3. 如果N=k+i,第k+i个被选择的概率为p=k/(k+i)=k/N,前k+i-1(N-1)个被选择的概率为
> > p=k/(k+i-1) * (i/(k+i) + (k/(k+i) * (k-1)/k) = k/(k+i-1) * (i/(k+i) +
> > (k-1)/(k+i)) =
> > k/(k+i-1) * (k+i-1)/(k+i) = k/(k+i) = k/N
>
> > 2008/5/9 Googol Lee <
googol...@gmail.com>:
>
> >> 但取出来的一定是k个么?
>
> >> 2008/5/9 lbaby <
lba...@yahoo.com.cn>:
> >> > 1,我想出了一个办法:
> >> > 从头遍历,然后计数,对 n 属于 1-N ,取 random/n % k 存入 结果中
>
> >> > On May 8, 7:06 pm, pongba <
pon...@gmail.com> wrote:
> >> >> 有点火星,但肯定有人没做过的:-) ... 比如我...
>
> >> >> 1.
>
> >> 给你一个长度为N的链表。N很大,但你不知道N有多大。你的任务是从这N个元素中随机取出k个元素。你只能遍历这个链表一次。你的算法必须保证取出的元素恰好有k个,且它们是完全随机的(出现概率均等)。
>
> >> >> 2.
>
> >> 给你一个数组A[1..n],请你在O(n)的时间里构造一个新的数组B[1..n],使得B[i]=A[1]*A[2]*...*A[n]/A[i]。你不能使用除法运算。
> if(you.MailTo("
dugugu...@gmail.com ") || you.MailTo("
>
fanh...@mails.tsinghua.edu.cn "))return true;
> if(you.PhoneTo("13488810330") || you.PhoneTo("01062778689"))return true;
> if(you.QQTo("120628812") || you.MSNTo("
dugugu...@hotmail.com"))return true;