蓄水池采样算法
蓄水池采样算法
证明
- N个元素种随机取m个数;array[N+1]放所有数据,下标从1开始
- 池子大小m,当前要进入到池子的数据是array[count],count范围[1,N]
- count <= m时,也就是池子还没满就直接放入
- count > m 时, 以m/count的概率决定是否要将array[count]放入池子
- 池子中任意一个元素被array[count]替换的概率是1/m * m/count = 1/count,不被array[count]替换的概率就是1- 1/count=(count-1)/count
- array[t]会保存在池子里的概率 = P(被选中替换到池子里)P(不被后续的替换) = P(被选中替换到池子里)P(不被array[t+1]替换)P(不被array[t+2]替换)...P(不被array[N]替换)=(m/t)(t/(t+1))((t+1)/(t+2))...*((N-1)/N)=m/N
- Leetcode:382链表随机节点
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode() {} * ListNode(int val) { this.val = val; } * ListNode(int val, ListNode next) { this.val = val; this.next = next; } * } */ class Solution { // int[] array; // // public Solution(ListNode head) { // List<Integer> list = new ArrayList<>(); // while (head != null) { // list.add(head.val); // head = head.next; // } // array = list.stream().mapToInt(Integer::intValue).toArray(); // } // // public int getRandom() { // return array[new Random().nextInt(array.length)]; // } ListNode head; public Solution(ListNode head) { this.head = head; } public int getRandom() { ListNode cur = head; // 池子容量是1 // 记录是第几个元素要进入池子 int count = 0; Integer res = null; while (cur != null) { count++; // 小于池子容量时直接放入 if (res == null) { res = cur.val; } // 大于容量时,以1/count的概率去决定要不要用这个新元素替换池子里的元素 if (new Random().nextInt(count) == 0) { // 换掉池子里的一个任意元素(此题池子为1只有一个元素) res = cur.val; } cur = cur.next; } return res; } }
本文作者:sprinining
本文链接:https://www.cnblogs.com/sprinining/p/16377699.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
算法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步