给定一个整数 n 和一个 无重复 黑名单整数数组 blacklist 。设计一种算法,从 [0, n - 1] 范围内的任意整数中选取一个 未加入 黑名单 blacklist 的整数。任何在上述范围内且不在黑名单 blacklist 中的整数都应该有 同等的可能性 被返回。
优化你的算法,使它最小化调用语言 内置 随机函数的次数。
实现 Solution 类:
Solution(int n, int[] blacklist) 初始化整数 n 和被加入黑名单 blacklist 的整数
int pick() 返回一个范围为 [0, n - 1] 且不在黑名单 blacklist 中的随机整数
输入
["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
1 <= n <= 109
0 <= blacklist.length <= min(105, n - 1)
0 <= blacklist[i] < n
blacklist 中所有值都 不同
pick 最多被调用 2 * 104 次
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/random-pick-with-blacklist
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
请大佬移步到官方题解。
- class Solution {
- unordered_map<int, int> b2w;
- int bound;
-
- public:
- Solution(int n, vector<int> &blacklist) {
- int m = blacklist.size();
- bound = n - m;
- unordered_set<int> black;
- for (int b: blacklist) {
- if (b >= bound) {
- black.emplace(b);
- }
- }
-
- int w = bound;
- for (int b: blacklist) {
- if (b < bound) {
- while (black.count(w)) {
- ++w;
- }
- b2w[b] = w++;
- }
- }
- }
-
- int pick() {
- int x = rand() % bound;
- return b2w.count(x) ? b2w[x] : x;
- }
- };
-
-
- /**
- * Your Solution object will be instantiated and called as such:
- * Solution* obj = new Solution(n, blacklist);
- * int param_1 = obj->pick();
- */