398.随机数索引
- 方法一:哈希表
用哈希表map记录nums[i]的所有索引下标,pick时,取出map对应的下标列表,随机选择其中一个下标并返回。
复杂度:时间复杂度:O(N);空间复杂度:O(N);
- 方法二:水塘抽样
如果数组以文件形式存储,且文件大小远超内存大小,我们无法通过读文件,将所有下标保存在内存中,因此需要找到一种空间复杂度更低的算法。
我们可以设计如下算法实现pick操作:
遍历nums,当我们第一次遇到值为target的元素时,随机选择区间[0, i)的一个整数,如果其等于0,则将该返回值置为该元素的下标,否则返回值不变。
设nums中有k个值为target的元素,该算法会保证这k个元素的下标成为返回值的概率均为1/k,证明如下:

class Solution { int[] nums; Random random; public Solution(int[] nums) { this.nums = nums; random = new Random(); } public int pick(int target) { int ans = 0; for (int i = 0, cnt = 0; i < nums.length; ++i) { if (nums[i] == target) { ++cnt; // 第 cnt 次遇到 target if (random.nextInt(cnt) == 0) { ans = i; } } } return ans; } }
复杂度:时间复杂度:初始化为O(1),pick为O(N);空间复杂度:O(1);
浙公网安备 33010602011771号