题意

给定一个可能含有重复元素的整数数组,要求随机输出给定的数字的索引。 您可以假设给定的数字一定存在于数组中。

注意:

数组大小可能非常大。 使用太多额外空间的解决方案将不会通过测试。

示例:

int[] nums = new int[] {1,2,3,3,3};
Solution solution = new Solution(nums);
// pick(3) 应该返回索引 2,3 或者 4。每个索引的返回概率应该相等。
solution.pick(3);
// pick(1) 应该返回 0。因为只有nums[0]等于1。
solution.pick(1);

题解

蓄水池抽样问题

首先从最简单的例子出发:数据流只有一个数据。我们接收数据,发现数据流结束了,直接返回该数据,该数据返回的概率为1。

看来很简单,那么我们试试难一点的情况:假设数据流里有两个数据。我们读到了第一个数据,这次我们不能直接返回该数据,因为数据流没有结束。我们继续读取第二个数据,发现数据流结束了。因此我们只要保证以相同的概率返回第一个或者第二个数据就可以满足题目要求。因此我们生成一个0到1的随机数R,如果R小于0.5我们就返回第一个数据,如果R大于0.5,返回第二个数据。

接着我们继续分析有三个数据的数据流的情况。为了方便,我们按顺序给流中的数据命名为1、2、3。我们陆续收到了数据1、2和前面的例子一样,我们只能保存一个数据,所以必须淘汰1和2中的一个。应该如何淘汰呢?不妨和上面例子一样,我们按照二分之一的概率淘汰一个,例如我们淘汰了2。继续读取流中的数据3,发现数据流结束了,我们知道在长度为3的数据流中,如果返回数据3的概率为1/3,那么才有可能保证选择的正确性。也就是说,目前我们手里有1,3两个数据,我们通过一次随机选择,以1/3的概率留下数据3,以2/3的概率留下数据1。那么数据1被最终留下的概率是多少呢?

数据1被留下:(1/2) * (2/3) = 1/3
数据2被留下概率:(1/2) * (2/3) = 1/3
数据3被留下概率:1/3

这个方法可以满足题目要求,所有数据被留下返回的概率一样!

因此,我们做一下推论:

假设当前正要读取第n个数据,则我们以 1/n 的概率留下该数据,否则留下前 n-1 个数据中的一个。以这种方法选择,所有数据流中数据被选择的概率一样。

//C++
class Solution {private:vector<int> nums;
public:Solution(vector<int>& nums) {for(int num : nums){this->nums.push_back(num);}}int pick(int target) {int index = 0;int n = 0;for(int i = 0; i < nums.size(); i++){if(nums[i] == target){n++;if(rand() % n == 0)index = i;}     }return index;   }
};/*** Your Solution object will be instantiated and called as such:* Solution* obj = new Solution(nums);* int param_1 = obj->pick(target);*/

LeetCode系列398—随机数索引(蓄水池抽样)相关推荐

  1. 398. 随机数索引(哈希表预处理 Or 蓄水池抽样)

    文章目录 Question Ideas 1.Answer( Java ) `⚡️ getOrDefault(Object key, V defaultValue)` Code①( HashMap 实现 ...

  2. leetcode刷题记录-398. 随机数索引

    前言 今天的题目为中等,跟之前碰到过的一道题思路很相似,利用map表来空间换时间,以此来做到节省时间复杂度. 每日一题 今天的题目是 398. 随机数索引,难度为中等 给你一个可能含有 重复元素 的整 ...

  3. Java实现 LeetCode 398 随机数索引

    398. 随机数索引 给定一个可能含有重复元素的整数数组,要求随机输出给定的数字的索引. 您可以假设给定的数字一定存在于数组中. 注意: 数组大小可能非常大. 使用太多额外空间的解决方案将不会通过测试 ...

  4. 398. 随机数索引 ( 设计 )

    LeetCode:398. 随机数索引 要求返回 target 在数组中随机的一个下标 留意,这个数组不是有序的,有序的话使用 二分查找. 这里无序的, 直接保存相同元素的下标,然后随机返回 AC C ...

  5. LeetCode 398. 随机数索引(概率)

    1. 题目 给定一个可能含有重复元素的整数数组,要求随机输出给定的数字的索引. 您可以假设给定的数字一定存在于数组中. 注意: 数组大小可能非常大. 使用太多额外空间的解决方案将不会通过测试. 示例: ...

  6. LeetCode 398. 随机数索引

    1.题目 https://leetcode-cn.com/problems/random-pick-index/ 2.题解 蓄水池抽样 其思路就是循环之后先判断一下这个数在数组中的索引, 然后随机选出 ...

  7. Leetcode 398. 随机数索引 解题思路及C++实现

    解题思路: 题目对空间复杂度有要求.在构造函数中,应该要先把nums数组拷贝一下. 在pick函数中,必然要遍历数组nums,这样才能得到 target 值对应的所有索引,之后再生成一个随机数,返回任 ...

  8. Leetcode 398.随机数索引

    原题链接:Leetcode 398. Random Pick Index Given an integer array nums with possible duplicates, randomly ...

  9. leetcode 398. Random Pick Index | 398. 随机数索引(Java)

    题目 https://leetcode.com/problems/random-pick-index/ 题解 常规思路,先用 map 存一串,取的时候从 map 对应的串中随机拿一个就 ok. cla ...

最新文章

  1. 利用VS+MFC+Opencv显示图像和视频所需添加类(CvvImage.h和CvvImage.cpp的源码)。
  2. VUE中让由全局变量添加生成的新数组不随全局变量的变化而变化
  3. 硬件——STM32,GPIO篇
  4. 【机器学习】粗糙集属性约简—Attribute Reduction
  5. android nv21图片格式,Android -- 将NV21图像保存成JPEG
  6. gulp排除已压缩文件思路
  7. 剑指OFFER之把数组排成最小的数(九度OJ1504)
  8. 美区苹果id被禁用原因和解除限制方法
  9. google Play 应用被下架暂停
  10. html中 videojs 播放m3u8文件【方式一】
  11. Android 通过FTP方式下载服务器文件
  12. 优思学院|六西格玛DMAIC,傻傻搞不清?
  13. 信号分析——导数(Java/Matlab)
  14. 如何做一个高级的文本编辑器 textarea,拥有快捷键操作
  15. MIMO信道的信道容量
  16. PPT - 如何从 PowerPoint 幻灯片中删除幻灯片编号
  17. 怎样才能使自己的经络运行顺畅呢?
  18. 推荐一个整理免费可商用字体的网站——猫啃网
  19. IOS真机调试包 iOS15.0
  20. 运维人员如何批量修改web服务器密码

热门文章

  1. 服务端为什么需要心跳(保活)机制
  2. 赤峰查号录-针对赤峰地区的综合类信息服务平台
  3. 胶囊网络(Capsule)学习笔记
  4. vb.net按式样比较字符串
  5. 【java】java定时任务1秒调度一次会怎么样
  6. 银行卡收单业务____轧差
  7. 【python实战(1),中信银行Java笔试题库
  8. 出现“Windows资源管理器已停止工作”错误
  9. 小鹏发布会上硬刚特斯拉AutoPilot:有视频有真相,特斯拉不懂中国路况-1
  10. java defunct怎么杀掉_杀死Linux中的defunct进程(僵尸进程)的方法指南