1. 题目
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);
2. 题解
2022-04-25 AC, 定长的就比较简单, 直接map, 如果实际中是流的数据方式更推荐”蓄水池抽样”解法
<?php
/**
* Created by PhpStorm
* User: jtahstu
* Time: 2022/4/25 10:05
* Des: 398. 随机数索引
* https://leetcode-cn.com/problems/random-pick-index/
* 给定一个可能含有重复元素的整数数组,要求随机输出给定的数字的索引。 您可以假设给定的数字一定存在于数组中。
* 注意:数组大小可能非常大。 使用太多额外空间的解决方案将不会通过测试。
*/
class Solution
{
private $list;
/**
* @param Integer[] $nums
*/
function __construct($nums)
{
foreach ($nums as $k => $num) {
$this->list[$num][] = $k;
}
}
/**
* @param Integer $target
* @return Integer
*/
function pick($target)
{
$indexs = $this->list[$target];
return $indexs[rand(0, count($indexs) - 1)];
}
}
/**
* Your Solution object will be instantiated and called as such:
* $obj = Solution($nums);
* $ret_1 = $obj->pick($target);
*/
$solution = new Solution([1, 2, 3, 3, 3]);
var_dump($solution->pick(3));
var_dump($solution->pick(1));
/**
* 执行用时:116 ms, 在所有 PHP 提交中击败了100.00%的用户
* 内存消耗:39.1 MB, 在所有 PHP 提交中击败了50.00%的用户
* 通过测试用例:14 / 14
*/
- 咱这属于哈希表预处理(定长数据流)
2. 另一个解法是蓄水池抽样(不定长数据流)
关于该解法为啥选取的概率相同, 可谷歌证明方式 ```java class Solution { Random random = new Random(); int[] nums; public Solution(int[] _nums) {
} public int pick(int target) {nums = _nums;
}int n = nums.length, ans = 0; for (int i = 0, cnt = 0; i < n; i++) { if (nums[i] == target) { cnt++; if (random.nextInt(cnt) == 0) ans = i; } } return ans;
```