leetcode382-链表随机节点&蓄水池算法&多益笔试

题目:

给定一个单链表,随机选择链表的一个节点,并返回相应的节点值。保证每个节点被选的概率一样。

进阶:
如果链表十分大且长度未知,如何解决这个问题?你能否使用常数级空间复杂度实现?

示例:

// 初始化一个单链表 [1,2,3].
ListNode head = new ListNode(1);
head.next = new ListNode(2);
head.next.next = new ListNode(3);
Solution solution = new Solution(head);

// getRandom()方法应随机返回1,2,3中的一个,保证每个元素被返回的概率相等。
solution.getRandom();

思路:这个题是蓄水池抽样问题,将相关的知识点补充在这里。原文链接:https://blog.csdn.net/huagong_adu/article/details/7619665

蓄水池抽样问题:从一个包含n个对象的列表S中随机选取k个对象,n为一个非常大或者不知道的值。通常情况下,n是一个非常大的值,大到无法一次性把所有列表S中的对象都放到内存中。我们这个问题是蓄水池抽样问题的一个特例,即k=1。

解法:我们总是选择第一个对象,以1/2的概率选择第二个,以1/3的概率选择第三个,以此类推,以1/m的概率选择第m个对象。当该过程结束时,每一个对象具有相同的选中概率,即1/n,证明如下。

        证明:第m个对象最终被选中的概率P=选择m的概率*其后面所有对象不被选择的概率,即
                                                      

                 

                                                           

虽然这个道理挺好理解的,但是地下这个代码还是不太懂。。。

nextInt()函数用于生产随机数,nextInt(n)用于生成一个范围在(0,n-1)之间的随机数。

代码:

class Solution {
    private ListNode head;

    /** @param head The linked list's head.
        Note that the head is guaranteed to be not null, so it contains at least one node. */
    public Solution(ListNode head) {
          this.head = head;
    }
    
    /** Returns a random node's value. */
    public int getRandom() {
       Random random = new Random();//一个随机数
        int result = head.val;
        ListNode currNode = head;
        for(int i=1; currNode.next!=null; i++) {
            currNode = currNode.next;
            if((random.nextInt(i + 1)) == i) {//这块的意思可能是这个随机数可能是以1/i的概率去到i这个数,此时我们就对应的取出这

//个位置的节点
                result = currNode.val;
            }
        }
        return result;

    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值