Leetcode 382. Linked List Random Node

本文介绍了一种在给定单链表中返回一个随机节点值的方法,确保每个节点被选取的概率相同。特别地,在链表长度未知且极大时,提出了一种无需额外空间的有效解决方案——水库抽样算法。

Given a singly linked list, return a random node's value from the linked list. Each node must have the same probability of being chosen.

Follow up:
What if the linked list is extremely large and its length is unknown to you? Could you solve this efficiently without using extra space?

Example:

// Init a singly linked list [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() should return either 1, 2, or 3 randomly. Each element should have equal probability of returning.
solution.getRandom();

 

本题可以用reservoir sampling来解决不明list长度的情况下平均概率选择元素的问题。

假设在[x_1,...,x_n]只选一个元素,要求每个元素被选中的概率都是1/n,但是n未知。 其中 random.randint(0, cnt) == 0: 的概率是1/(cnt+1)。reservoir sampling的证明可以使用归纳法(induction)。

 

 1 class Solution(object):
 2 
 3     def __init__(self, head):
 4         """
 5         @param head The linked list's head.
 6         Note that the head is guaranteed to be not null, so it contains at least one node.
 7         :type head: ListNode
 8         """
 9         self.head = head
10 
11     def getRandom(self):
12         """
13         Returns a random node's value.
14         :rtype: int
15         """
16         cnt = 0
17         head = self.head
18         while head:
19             if random.randint(0, cnt) == 0:
20                 ans = head.val
21             head = head.next
22             cnt += 1
23         return ans

 

本题的一个推广是如何在[x_1,...,x_n]中选出k个元素。并且每个x_i被选中的概率都一样,而且n未知。

1. if i <= k, T_i = T_{i-1}\cup x_i

2. else with p = k/i replace one element in T_{i-1} with x_i with p=1/k。

证明同样可以用归纳法。

 

转载于:https://www.cnblogs.com/lettuan/p/6218985.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值