398. Random Pick Index

类似问题:

382. Linked List Random Node

问题:

给定一组数(可能有重复的数字),

求随机取得数字=target的index。

⚠️ 注意:取得每个数的概率要相同。

Example 1:
Input
["Solution", "pick", "pick", "pick"]
[[[1, 2, 3, 3, 3]], [3], [1], [3]]
Output
[null, 4, 0, 2]

Explanation
Solution solution = new Solution([1, 2, 3, 3, 3]);
solution.pick(3); // It should return either index 2, 3, or 4 randomly. Each index should have equal probability of returning.
solution.pick(1); // It should return 0. Since in the array only nums[0] is equal to 1.
solution.pick(3); // It should return either index 2, 3, or 4 randomly. Each index should have equal probability of returning.
 

Constraints:

1 <= nums.length <= 2 * 104
-231 <= nums[i] <= 231 - 1
target is an integer from nums.
At most 104 calls will be made to pick.

  

解法:math,概率。

解法一:unordered_map<数字,该数字的所有index(vector)>

初始化构建该map

在随机抽取中:

取得target对应的所有index vector

从中任意取一个:vector[rand()/vector.size]

代码参考:

 1 class Solution {
 2 public:
 3     unordered_map<int, vector<int>> mp;
 4     Solution(vector<int>& nums) {
 5         for(int i=0; i<nums.size(); i++) {
 6             mp[nums[i]].push_back(i);
 7         }
 8     }
 9     
10     int pick(int target) {
11         int sz = mp[target].size();
12         return mp[target][rand()%sz];
13     }
14 };
15 
16 /**
17  * Your Solution object will be instantiated and called as such:
18  * Solution* obj = new Solution(nums);
19  * int param_1 = obj->pick(target);
20  */

解法二:math,概率

思想同382. Linked List Random Node

  • 不在初始化做什么。
  • 在抽取时,遍历所有数字,
    • 在当前数字的遍历中,若满足概率1/i的时候,进行res赋值。
  • 一直到遍历完毕。
  • 返回res。

⚠️ 只是,对于本题:当遍历到当前数字,若!=target则continue。不进行任何操作。

只有是target的index,才进行概率计算 i++

⚠️ 注意:在初始化res,为第一个(i==1)访问到的target。

因为此时选取到该index的可能=1/i = 1/1 =1。

代码参考:

 1 class Solution {
 2 public:
 3     vector<int> _num;
 4     Solution(vector<int>& nums) {
 5         _num = nums;
 6     }
 7     
 8     int pick(int target) {
 9         int res = -1;
10         int i=0;
11         for(int k=0; k<_num.size(); k++) {
12             if(_num[k]!=target) continue;
13             i++;
14             if(i==1) res=k;
15             else {
16                 int rd = rand()%i;
17                 if(0==rd) res=k;
18             }
19         }
20         return res;
21     }
22 };
23 
24 /**
25  * Your Solution object will be instantiated and called as such:
26  * Solution* obj = new Solution(nums);
27  * int param_1 = obj->pick(target);
28  */
原文地址:https://www.cnblogs.com/habibah-chang/p/14621794.html