蓄水池抽样算法
简单来说 就是我们现在有一个链表
我们从头指针遍历到尾指针
我们最开始设一个变量
遍历过程中 它可以指向任一个当前节点
使得遍历结束时 这个变量指向任何一个节点的概率是相等的
这个变量的计算方法如下:
我们遍历到第i个节点时
都使之有1/i的概率被选到
遍历到头结点时 因为只有自己 被选到的概率是1
遍历到第二个时 第二个被选到的概率是1/2 而不被选到(即仍选头结点)的概率也是1/2
当摇到第i个的时候,当前节点被选到的概率是1/i 而不被选到的概率是(i-1)/i
那么 前i-1个节点被选到的概率就是(i-1)/i
那么前i-2个节点被选到的概率就是(i-2)/(i-1) * (i-1)/i = (i-2)/i
即 每个点被选到的概率都是1/i
我们产生一个[1,i]的随机数x
若x == i(有1/i的概率)则 让那个变量记录第i个节点
最终变量记录的节点的值即为所求
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
import random
class Solution:
def __init__(self, head: ListNode):
"""
@param head The linked list's head.
Note that the head is guaranteed to be not null, so it contains at least one node.
"""
self.head = head
def getRandom(self) -> int:
"""
Returns a random node's value.
"""
cur = self.head
index = 1
res = cur.val
while cur!= None:
random_int = random.randint(1,index)
if random_int == index:
res = cur.val
index += 1
cur = cur.next
return res