Given a blacklist B containing unique integers from [0, N), write a function to return a uniform random integer from [0, N) which is NOT in B.

Optimize it such that it minimizes the call to system’s Math.random().

Note:

  1. 1 <= N <= 1000000000
  2. 0 <= B.length < min(100000, N)
  3. [0, N) does NOT include N. See interval notation.

Example 1:

Input:
["Solution","pick","pick","pick"]
[[1,[]],[],[],[]]
Output: [null,0,0,0]

Example 2:

Input:
["Solution","pick","pick","pick"]
[[2,[]],[],[],[]]
Output: [null,1,1,1]

Example 3:

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

Example 4:

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

Explanation of Input Syntax:

The input is two lists: the subroutines called and their arguments. Solution's constructor has two arguments, N and the blacklist Bpick has no arguments. Arguments are always wrapped with a list, even if there aren't any.

这道题让我们生成一个N以内的随机数,但是还给了一个黑名单,意思是黑名单里面的数字不能被选到。于是博主最先想到的方法就是用拒绝采样Rejection Sampling来做,因为之前做过使用该方法的两道题 Implement Rand10() Using Rand7() 和 Generate Random Point in a Circle,所以可以立马想到。思路其实很简单,就是随机一个数,如果是黑名单里的,那么就重新随机。为了提高在黑名单中查找数字的速度,我们将所有黑名单的数字放到一个HashSet中,这样我们就拥有了常数级查找的速度,看似一切水到渠成,燃鹅被OJ强行打脸,TLE!那么换一种思路吧,既然你有黑名单,那么林北就有白名单,把所有没被block的数字都放到一个新数组中,然后随机生成数组坐标不就完了。燃鹅x2,又被OJ放倒了,MLE!不准用这么多内存。岂可修,真的没别的办法了嘛?!还好方法解答贴中给了一种使用HashMap的方法来做,博主仔细研读了一番,发现确实秒啊!既然数字总共有N个,那么减去黑名单中数字的个数,就是最多能随机出来的个数。比如N=5,黑名单中有两个数{2, 4},那么我们最多只能随机出三个,但是我们如果直接rand()%3,会得到0,1,2,我们发现有两个问题,一是黑名单中的2可以随机到,二是数字3没法随机到。那么我们想,能不能随机到0或1则返回其本身,而当随机到2到时候,我们返回的是3,我们需要建立这样的映射,这就是使用HashMap的动机啦。我们首先将超过N - blacklist.size()的数字放入一个HashSet,这里就把{3, 4}放进去了,然后我们遍历blacklist中的数字,如果在HashSet中的话,就将其删除,这样HashSet中就只有{3}了,这个需要建立映射的数字,而用什么数字建立,当然是用黑名单中的数字了,遍历黑名单中的数字,如果小于N - blacklist.size()的话,说明是有可能随机到的,我们和HashSet中的第一个数字建立映射,然后我们可以用个iterator,指向HashSet中的下一个数组,然后继续建立映射。从而实现在pick函数中的移魂换影大法了,先随机个数字,如果有映射,则返回映射值,否则返回原数字,参见代码如下:

class Solution {
public:
Solution(int N, vector<int> blacklist) {
unordered_set<int> st;
len = N - blacklist.size();
for (int i = len; i < N; ++i) st.insert(i);
for (int num : blacklist) st.erase(num);
auto it = st.begin();
for (int num : blacklist) {
if (num < len) m[num] = *it++;
}
} int pick() {
int k = rand() % len;
return m.count(k) ? m[k] : k;
} private:
unordered_map<int, int> m;
int len;
};

类似题目:

Random Pick with Weight

Random Pick Index

参考资料:

https://leetcode.com/problems/random-pick-with-blacklist/

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Random Pick with Blacklist 带黑名单的随机选取的更多相关文章

  1. 710. Random Pick with Blacklist - LeetCode

    Question 710. Random Pick with Blacklist Solution 题目大意:给一个N,表示一个范围[0,N),给一个黑名单列表blacklist,其中blacklis ...

  2. [LeetCode] Random Pick with Weight 根据权重随机取点

    Given an array w of positive integers, where w[i] describes the weight of index i, write a function  ...

  3. [Swift]LeetCode710. 黑名单中的随机数 | Random Pick with Blacklist

    Given a blacklist B containing unique integers from [0, N), write a function to return a uniform ran ...

  4. 710 Random Pick with Blacklist

    1. 问题 给定一个黑名单,包含[0, N)的一些数,从[0, N)之间的非黑名单数中随机采样一个值. 2. 思路 字典映射 (1)计算黑名单数的长度,记作B,因为已经排除掉了B个元素,所以最后是从N ...

  5. [LeetCode] Random Pick Index 随机拾取序列

    Given an array of integers with possible duplicates, randomly output the index of a given target num ...

  6. Leetcode: Random Pick Index

    Given an array of integers with possible duplicates, randomly output the index of a given target num ...

  7. LeetCode 528. Random Pick with Weight

    原题链接在这里:https://leetcode.com/problems/random-pick-with-weight/ 题目: Given an array w of positive inte ...

  8. 398. Random Pick Index - LeetCode

    Question 398. Random Pick Index Solution 思路:重点是如果数据中有多个数target相等,要从这些数中随机取一个,根据例题 假设输入是: int[] nums ...

  9. [LeetCode] Random Point in Non-overlapping Rectangles 非重叠矩形中的随机点

    Given a list of non-overlapping axis-aligned rectangles rects, write a function pick which randomly ...

随机推荐

  1. JENKINS针对不同项目组对用户进行权限分配

    权限需求 因JENKINS上存有de(开发).te(测试).re(预发布)等三个不同环境的项目,同时因为项目需求,需要对不同的开发及测试人员配置不同的jenkins权限,即以项目为单位,对不同人员进行 ...

  2. vue-cli3.X 打包后上传服务器刷新报 404的问题

    vue-cli3.X 默认配置 比2.X体验好很多,比如路由 如图,本地正常,传到服务器,因为二级目录,刷新就404,或 502等,找不到文件 nginx解决: location /{ error_p ...

  3. dubbo和zikkeper的使用

    1.先来一段异常看看:No provider available for the service 16:05:25.755 [localhost-startStop-1] WARN o.s.w.c.s ...

  4. 使用Roslyn编译项目的示例

    using System; using System.Collections.Generic; using System.IO; using Microsoft.CodeAnalysis; using ...

  5. Spring+Shiro的踩坑

    今天想给某个Service的某些方法添加Cache,这个记为A,用的springboot,照常在方法上加上Cacheable注解,测试缓存生效,搞定.然后再在第二个Service,记为B,添加Cach ...

  6. 用agular2做文件上传功能杂记-遁地龙卷风

    (-1)功能描述 写一个功能,前台发起执行请求,后台执行任务,前台可以获取执行的进度,并取得最后的执行状态. (0)angular2 $http文件上传 这里之所以不用angular-file-upl ...

  7. Stm32 GPIO复习

    地点:中图四楼. 1.七个寄存器 配置寄存器:GPIOx_CPL.GPIOx_CPH; 数据寄存器:GPIOx_IDR.GPIOx_ODR: 置位/复位寄存器:GPIOx_BSRR 复位寄存器:GPI ...

  8. SpringBoot使用Redis共享用户session信息

    SpringBoot引入Redis依赖: <dependency> <groupId>org.springframework.boot</groupId> < ...

  9. python 三大框架之一Django入门

    Django 是从真实世界的应用中成长起来的,它是由 堪萨斯(Kansas)州 Lawrence 城中的一个 网络开发小组编写的. 它诞生于 2003 年秋天,那时 Lawrence Journal- ...

  10. pythonのsqlalchemy多对多关系

    现在来设计一个能描述“图书”与“作者”的关系的表结构,需求是 一本书可以有好几个作者一起出版 一个作者可以写好几本书 #!/usr/bin/env python from sqlalchemy imp ...