398. Random Pick Index
类似问题:
问题:
给定一组数(可能有重复的数字),
求随机取得数字=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 */