给你一个链表和一个 random函数, 设计一个算法能随机返回链表的某个节点, 要求每个节点被返回的概率一样。限制条件是只能遍历链表一次并且不能用额外空间。...

某全球著名搜索引擎公司面试题。

说实话这类型的题如果你不知到真的很难解。  可能的思考方式是,(假设总共有n个节点,n是未知)当我走到第x个节点的时候,可以利用的信息是我已经走了x步了,需要想一种方式决定我是否选该节点,并且这种方式让当前节点被选中的概率是1/n.

 

这里的关键点时,解决的方法是,当走到第x步时,以1/x的概率决定是否选第x个。第x+1步时,以1/(x+1)步的概率决定是否选中第x+1个。这样第x个被当作最后结果的概率是,第x个被选中,第x个之后的(x+1,x+2,...,n)都没被选中。其概率为 1/x * x/(x+1) *(x+1)/(x+2) ... (n-1)/n  = 1/n 。


示例代码如下(未考虑输入错误检查):

Node* GetRandomNode(Node* header)

{

         Node* p = header;

         Node* result = nil;

         int count =0;

         for(; p != null; p = p->next)

        {

             count++;

             if(0 == random(count))

             {

                    result = p;

             }

             p = p->next;

        }

        return result;        

}

转载于:https://www.cnblogs.com/MobileDevelop/archive/2010/09/26/1782444.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值