蓄水池抽样算法 leetcode 398 382
382 https://leetcode-cn.com/problems/linked-list-random-node/submissions/
//只抽取一个元素,使得这个元素是等可能的 int getRandom1(ListNode head){ Random r = new Random(); int i = 0; int result= 0; ListNode p = head; while(p!=null){ i++; if(r.nextInt(i) == 0){// 咋 [0,i) 之间的 等于0的概率为 1/i 这样就能保证所有的元素最后的概率为 1/n result = p.val; } p = p.next; } return result; }
398等概率的找到target https://leetcode-cn.com/problems/random-pick-index/submissions/
class Solution { private int[] nums; private Random random = new Random(); public Solution(int[] nums) { this.nums = nums; } public int pick(int target) { int result = 0; int k = 0; for(int i = 0; i< nums.length; i++){ //先找到满足条件的元素 if(nums[i] == target){ //k表示nums中等于target的数字个数 //需要保证这个数字被选择的概率是 1/k; //那就需要使用在 在[0,k)之间选择数字 使得 概率为 1/k k++; if(random.nextInt(k) == 0){ //在[0,k)之间选择数字 使得 概率为 1/k //每次以1/k的概率更新结果 result = i; } } } return result; } } /** * Your Solution object will be instantiated and called as such: * Solution obj = new Solution(nums); * int param_1 = obj.pick(target); */
泛化--- 未知长度,k个元素 等可能
需要随机选择 k 个数, 保证每个都是等可能的,只能遍历一次
//抽取k个元素,使得k个元素是等可能的 在这个k个元素中任意一个i 的概率为 k/n //只要保证任意的在 被选择的时候 保证 概率为 k/i就行 int[] getRandomk(ListNode head,int k){ Random r = new Random(); int[] result = new int[k]; ListNode p = head; //step1: 先找到符合要求的元素 k个 //先将前面k个元素先选上 for (int i = 0; i < k && p!=null; i++) { result[i] = p.val; p = p.next; } int i = k; //step2: 保证概率 while(p!= null){ i++; //随机生成一个随机数 int j = r.nextInt(i);//先随机生成一个[0,i)之间的数 j if(j < k){//如果j 在 k 的范围内,则概率等可能的 概率 为 k/i 则可以替换 result[j] = p.val;//将做的新的选择 替换到result中 } p = p.next; } return result; }
---
import java.util.Random; /** * @ClassName GetRandom * @Description TODO * @Author Administrator * @Date 2022/4/8 10:03 * @Version 1.0 **/ public class GetRandom { //只抽取一个元素,使得这个元素是等可能的 int getRandom1(ListNode head){ Random r = new Random(); int i = 0; int result= 0; ListNode p = head; while(p!=null){ i++; if(r.nextInt(i) == 0){ result = p.val; } p = p.next; } return result; } //抽取k个元素,使得k个元素是等可能的 在这个k个元素中任意一个i 的概率为 k/n //只要保证任意的在 被选择的时候 保证 概率为 k/i就行 int[] getRandomk(ListNode head,int k){ Random r = new Random(); int[] result = new int[k]; ListNode p = head; //step1: 先找到符合要求的元素 k个 //先将前面k个元素先选上 for (int i = 0; i < k && p!=null; i++) { result[i] = p.val; p = p.next; } int i = k; //step2: 保证概率 while(p!= null){ i++; //随机生成一个随机数 int j = r.nextInt(i);//先随机生成一个[0,i)之间的数 j if(j < k){//如果j 在 k 的范围内,则概率等可能的 概率 为 k/i 则可以替换 result[j] = p.val;//将做的新的选择 替换到result中 } p = p.next; } return result; } }
本文来自博客园,作者:{zhongweiLeex},转载请注明原文链接:{https://www.cnblogs.com/lzw6/}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理