710. 黑名单中的随机数
给定一个整数 n
和一个 无重复 黑名单整数数组 blacklist
。设计一种算法,从 [0, n - 1]
范围内的任意整数中选取一个 未加入 黑名单 blacklist
的整数。任何在上述范围内且不在黑名单 blacklist
中的整数都应该有 同等的可能性 被返回。
优化你的算法,使它最小化调用语言 内置 随机函数的次数。
实现 Solution
类:
Solution(int n, int[] blacklist)
初始化整数n
和被加入黑名单blacklist
的整数int pick()
返回一个范围为[0, n - 1]
且不在黑名单blacklist
中的随机整数
示例 1:
输入 ["Solution", "pick", "pick", "pick", "pick", "pick", "pick", "pick"] [[7, [2, 3, 5]], [], [], [], [], [], [], []] 输出 [null, 0, 4, 1, 6, 1, 0, 4] 解释 Solution solution = new Solution(7, [2, 3, 5]); solution.pick(); // 返回0,任何[0,1,4,6]的整数都可以。注意,对于每一个pick的调用, // 0、1、4和6的返回概率必须相等(即概率为1/4)。 solution.pick(); // 返回 4 solution.pick(); // 返回 1 solution.pick(); // 返回 6 solution.pick(); // 返回 1 solution.pick(); // 返回 0 solution.pick(); // 返回 4
暴力
class Solution { public: vector<int> nums; Solution(int n, vector<int>& blacklist) { unordered_set<int> black_set(blacklist.begin(),blacklist.end()); for(int i = 0; i < n;i++) { if (black_set.find(i)!=black_set.end()) { continue; } nums.emplace_back(i); } } int pick() { int target = rand()%(nums.size());//生成闭区间[1,total]范围内的一个随机数 return nums[target]; } }; /** * Your Solution object will be instantiated and called as such: * Solution* obj = new Solution(n, blacklist); * int param_1 = obj->pick(); */
class Solution { public: vector<int> nums; int sz = 0; unordered_map<int,int> index_map; Solution(int n, vector<int>& blacklist) { sz = n-blacklist.size(); sort(blacklist.begin(),blacklist.end()); for(auto b : blacklist) { index_map[b] = 6666; } int last = n - 1; for(int i = 0; i < blacklist.size();i++) { int black = blacklist[i]; //// 如果 b 已经在区间 [sz, N) // 可以直接忽略 if (black >= sz) { continue; } // last 跳过所有黑名单中的数字 while(index_map.find(last)!=index_map.end()) { last--; } // 将黑名单中的索引映射到合法数字 index_map[black] = last; last--; } } int pick() { int index = rand()%(sz); if (index_map.find(index) != index_map.end()) { return index_map[index]; } return index; } }; /** * Your Solution object will be instantiated and called as such: * Solution* obj = new Solution(n, blacklist); * int param_1 = obj->pick(); */