来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/random-pick-index

题目描述

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

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

示例:

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);

解题思路

很明显这个题的场景是数据太大,内存无法全部加载,所以需要想办法压缩数据。

思路有两个:

一个是压缩数据,因为存在重复数据,所以可以合并数据并且记录重复次数,这样初始化时间复杂度为O(n), pick时间复杂度为O(1).

一个是使用数学规律,并不需要加载数据,所以初始化复杂度为O(1),但是在pick的时候记录遇到target的次数cnt,然后取一个[0,cnt)的随机数,如果这个随机数为0 则取这个索引,可以证明每个索引的概率是相同的。

证明:假设有k个target,那么在第cnt次取到索引的概率是

代码展示

哈希表暴力法:

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

水池抽样法:

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

运行结果

LeetCode-398 随机数索引的更多相关文章

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

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

  2. C#刷遍Leetcode系列连载 索引

    C#刷遍Leetcode系列文章 索引 索引(陆续发布中,请保持关注) C#刷遍Leetcode面试题系列连载(1) - 入门与工具简介 C#刷遍Leetcode面试题系列连载(2): No.38 - ...

  3. 398 Random Pick Index 随机数索引

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

  4. LeetCode 解题报告索引

    最近在准备找工作的算法题,刷刷LeetCode,以下是我的解题报告索引,每一题几乎都有详细的说明,供各位码农参考.根据我自己做的进度持续更新中......                        ...

  5. [Swift]LeetCode398. 随机数索引 | Random Pick Index

    Given an array of integers with possible duplicates, randomly output the index of a given target num ...

  6. [leetcode] 398. Random Pick Index

    我是链接 看到这道题,想到做的几道什么洗牌的题,感觉自己不是很熟,但也就是rand()函数的调用,刚开始用map<int, vector<int >>来做,tle,后来就想着直 ...

  7. LeetCode题目答案索引

    LeetCode-Two Sum LeetCode-Median of Two Sorted Arrays LeetCode-Longest Substring Without Repeating C ...

  8. [LeetCode] 398. Random Pick Index ☆☆☆

    Given an array of integers with possible duplicates, randomly output the index of a given target num ...

  9. 【数据结构与算法】蓄水池抽样算法(Reservoir Sampling)

    问题描述 给定一个数据流,数据流长度 N 很大,且 N 直到处理完所有数据之前都不可知,请问如何在只遍历一遍数据(O(N))的情况下,能够随机选取出 m 个不重复的数据. 比较直接的想法是利用随机数算 ...

  10. Swift LeetCode 目录 | Catalog

    请点击页面左上角 -> Fork me on Github 或直接访问本项目Github地址:LeetCode Solution by Swift    说明:题目中含有$符号则为付费题目. 如 ...

随机推荐

  1. 浏览器内存漫游解决方案(js逆向)

    //浏览器内存漫游解决方案(js逆向) //原理通过ast把所有的变量,参数中间值进行内存的存储 //搜索AST-hook,进入github //现在github的库下载下来 //anyproxy n ...

  2. Vuex极速入门

    01.什么是Vuex? 1.1.为什么需要状态管理? 在复杂的系统中,我们会把系统按照业务逻辑拆分为多个层次.多个模块,采用组件式的开发方式.而此时不同模块.父子模块之间的通信就成了一个问题. 为了解 ...

  3. Mac系统下word论文参考文献更新域

    写论文的时候可能会遇到后续要增加文献的情况 在参考文献增加后会发现文章中的交叉引用的序号并没有更新 下面分享两种情况的处理方法 一.更新全部域 首先确认自己的打印️项是选中的 2.  打开word偏好 ...

  4. vue移动端封装底部导航

    <template> <div class="myfooter flex-betweenCenter"> <router-link tag=" ...

  5. 基于Java的高并发多线程分片断点下载

    基于Java的高并发多线程分片断点下载 首先直接看测试情况: 单线程下载72MB文件 7线程并发分片下载72MB文件: 下载效率提高2-3倍,当然以上测试结果还和设备CPU核心数.网络带宽息息相关. ...

  6. 迁移学习(MixMatch)《MixMatch: A Holistic Approach to Semi-Supervised Learning》

    论文信息 论文标题:MixMatch: A Holistic Approach to Semi-Supervised Learning论文作者:David Berthelot, Nicholas Ca ...

  7. 什么是C语言

    什么是C语言? C语言是一门计算机语言 计算机语言是什么呢? 人和计算机交流的语言,如C/C++.Java.python 计算机语言的发展? 二进制语言(硬件-电-正电1/负电0 1010100101 ...

  8. Java 进阶P-8.15

    对象串行化 ObjectInputStream类 readObject() ObjectOutputStream类 writeObject() Serializable接口 对象的寿命通常随着生成该对 ...

  9. 普冉PY32系列(四) PY32F002/003/030的时钟设置

    目录 普冉PY32系列(一) PY32F0系列32位Cortex M0+ MCU简介 普冉PY32系列(二) Ubuntu GCC Toolchain和VSCode开发环境 普冉PY32系列(三) P ...

  10. 环形链表I、II(含代码以及证明)

    环形链表 解题思路 定义两个指针,一个快指针,一个慢指针,快指针每次移动两个节点,慢指针每次移动一个节点. 从头节点开始,让快慢指针同时移动,如果链表中有环,那么快慢指针一定会在某个节点相遇. 如果快 ...