LeetCode算法之蓄水池算法

目录

1.什么是蓄水池抽样

2.蓄水池抽样算法

3.LeetCode蓄水抽样经典算法题


一、什么是蓄水池抽样

大数据流中的随机抽样问题:当内存无法加载全部数据时,如何从包含未知大小的数据流中随机选取k个数据,并且要保证每个数据被抽取到的概率相等。蓄水池抽样算法就是用来解决该类问题的算法。

二、蓄水池抽样算法[1]

在不知道数据流大小(长度)的情况下,我们需要从数据流中随机抽取一个数据,每一个数据被抽到的概率是相同的。

遍历数据流,共计n次抽样(n为数据流大小,未知),我们假设第i次抽样中,从数组[0, i)中抽样一个整数,如果该整数等于0,那么保留该位置数据,否则数据不变。这样能保证每个数据被抽中的概率都是1/n。

证明:P(第i个数据成为最后被选中的数据)

        =P(第i次随机抽样的值=0)×P(第i+1次随机抽样的值≠0)×…×P(第n次随机抽样的值≠0)

        = \frac{1}{i}\times\left ( 1-\frac{1}{i+1} \right )\times\cdots \times \left ( 1-\frac{1}{n} \right )

        = \frac{1}{i}\times \frac{i}{i+1}\times \cdots \times \frac{n-1}{n}

        = \frac{1}{n}

3.LeetCode蓄水池抽样经典算法题

382. 链表随机节点

384. 打乱数组    该题采用Knuth 洗牌算法,非蓄水池

这里有一个大佬从两个角度讲解这个算法的等概率性[4]

洗牌算法[2]
共有 nn个不同的数,根据每个位置能够选择什么数,共有 n! 种组合。

题目要求每次调用 shuffle 时等概率返回某个方案,或者说每个元素都够等概率出现在每个位置中。

我们可以使用 Knuth 洗牌算法,在 O(n) 复杂度内等概率返回某个方案。

具体的,我们从前往后尝试填充 [0,n−1]该填入什么数时,通过随机当前下标与(剩余的)哪个下标进行值交换来实现。

对于下标 x而言,我们从[x,n−1] 中随机出一个位置与 x 进行值交换,当所有位置都进行这样的处理后,我们便得到了一个公平的洗牌方案。

对于下标为 0位置,从 [0,n−1] 随机一个位置进行交换,共有 n 种选择;下标为 1 的位置,从 [1,n−1] 随机一个位置进行交换,共有 n−1 种选择 ...

[3]

398. 随机数索引

497. 非重叠矩形中的随机点

# 382. 链表随机节点

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next

class Solution:

    def __init__(self, head: Optional[ListNode]):
        self.head=head

    def getRandom(self) -> int:
        node=self.head
        #notice,when i==1, the rand result must be 0 and the ans must be the val of the node.
        ans=0 
        #i represents the times of the sampling
        i=1
        while node:
            if randrange(i)==0:
                ans=node.val
            i+=1
            node=node.next
        return ans


#ps: the easist way: to make a list to save the vals


# Your Solution object will be instantiated and called as such:
# obj = Solution(head)
# param_1 = obj.getRandom()

引用

[1]https://leetcode.cn/problems/linked-list-random-node/solutions/1210211/lian-biao-sui-ji-jie-dian-by-leetcode-so-x6it/[2]https://leetcode.cn/problems/shuffle-an-array/solutions/1114958/gong-shui-san-xie-xi-pai-suan-fa-yun-yon-0qmy/[3]https://leetcode.cn/problems/shuffle-an-array/solutions/672603/da-luan-shu-zu-yi-ding-gong-ping-de-xi-p-21iy/[4]https://leetcode.cn/problems/shuffle-an-array/solutions/1115175/wei-rao-li-lun-jing-dian-xi-pai-suan-fa-11ona/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值