当前位置:网站首页>710. 黑名单中的随机数
710. 黑名单中的随机数
2022-06-26 12:33:00 【宫水三叶的刷题日记】
题目描述
这是 LeetCode 上的 「710. 黑名单中的随机数」 ,难度为 「困难」。
Tag : 「前缀和」、「二分」、「离散化」、「随机化」
给定一个整数 n 和一个 无重复 黑名单整数数组 blacklist。
设计一种算法,从 范围内的任意整数中选取一个 未加入 黑名单 blacklist 的整数。任何在上述范围内且不在黑名单 blacklist 中的整数都应该有 同等的可能性 被返回。
优化你的算法,使它最小化调用语言 内置 随机函数的次数。
实现 Solution 类:
Solution(int n, int[] blacklist)初始化整数n和被加入黑名单blacklist的整数int pick()返回一个范围为 且不在黑名单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
提示:
blacklist中所有值都 不同pick最多被调用 次
前缀和 + 二分
为了方便,我们记 blacklist 为 bs,将其长度记为 m。
问题本质是让我们从 范围内随机一个数,这数不能在 bs 里面。
由于 的范围是 ,我们不能在对范围在 且不在 bs 中的点集进行离散化,因为离散化后的点集大小仍很大。
同时 的范围是 ,我们也不能使用普通的拒绝采样做法,这样单次 pick 被拒绝的次数可能很大。
一个简单且绝对正确的做法是:「我们不对「点」做离散化,而利用 bs 数据范围为 ,来对「线段」做离散化」。
具体的,我们先对 bs 进行排序,然后从前往后处理所有的 ,将相邻 之间的能被选择的「线段」以二元组 的形式进行记录(即一般情况下的 ,),存入数组 list 中(注意特殊处理一下两端的线段)。
当处理完所有的 后,我们得到了所有可被选择线段,同时对于每个线段可直接算得其所包含的整数点数。
我们可以对 list 数组做一遍「线段所包含点数」的「前缀和」操作,得到 sum 数组,同时得到所有线段所包含的总点数(前缀和数组的最后一位)。
对于 pick 操作而言,我们先在 范围进行随机(其中 代表总点数),假设取得的随机值为 ,然后在前缀和数组中进行二分,找到第一个满足「值大于等于 」的位置(含义为找到这个点所在的线段),然后再利用该线段的左右端点的值,取出对应的点。
代码:
class Solution {
List<int[]> list = new ArrayList<>();
int[] sum = new int[100010];
int sz;
Random random = new Random();
public Solution(int n, int[] bs) {
Arrays.sort(bs);
int m = bs.length;
if (m == 0) {
list.add(new int[]{0, n - 1});
} else {
if (bs[0] != 0) list.add(new int[]{0, bs[0] - 1});
for (int i = 1; i < m; i++) {
if (bs[i - 1] == bs[i] - 1) continue;
list.add(new int[]{bs[i - 1] + 1, bs[i] - 1});
}
if (bs[m - 1] != n - 1) list.add(new int[]{bs[m - 1] + 1, n - 1});
}
sz = list.size();
for (int i = 1; i <= sz; i++) {
int[] info = list.get(i - 1);
sum[i] = sum[i - 1] + info[1] - info[0] + 1;
}
}
public int pick() {
int val = random.nextInt(sum[sz]) + 1;
int l = 1, r = sz;
while (l < r) {
int mid = l + r >> 1;
if (sum[mid] >= val) r = mid;
else l = mid + 1;
}
int[] info = list.get(r - 1);
int a = info[0], b = info[1], end = sum[r];
return b - (end - val);
}
}
时间复杂度:在初始化操作中:对 bs进行排序复杂度为 ;统计所有线段复杂度为 ;对所有线段求前缀和复杂度为 。在pick操作中:随机后会对所有线段做二分,复杂度为空间复杂度:
最后
这是我们「刷穿 LeetCode」系列文章的第 No.710 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode 。
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
更多更全更热门的「笔试/面试」相关资料可访问排版精美的 合集新基地
边栏推荐
- AD - 将修改后的 PCB 封装更新到当前 PCB 中
- 女性科学家的流失
- The most complete kubernetes core command of the latest version so far
- [redis series] redis learning 16. Redis Dictionary (map) and its core coding structure
- 2、 MySQL Foundation
- Introduction to the strongest swarm cluster one click deployment + hydrogen bomb level container management tool
- Implementing mixins scheme in applet
- One click deployment of your own community forum
- Jsonarray and jsonobject of fastjson [easy to understand]
- Scala-day02- variables and data types
猜你喜欢

Ad - update the modified PCB package to the current PCB

dried food! Yiwen will show you SD card, TF card and SIM card!
![[graduation season · advanced technology Er] I remember the year after graduation](/img/e7/8e1dafa561217b77a3e3992977a8ec.png)
[graduation season · advanced technology Er] I remember the year after graduation

TP5 thinkphp5 report serialization of'closure'is not allowed

Implementing mixins scheme in applet

MS17_ 010 utilization summary

Microservice governance (nocas)

"Pinduoduo and short video speed version", how can I roast!
女性科学家的流失

Build Pikachu shooting range and introduction
随机推荐
详细实操分享,下班刷了两小时的搞笑视频,一个月收益7000多
Iframe usage and contentwindow, parent and PostMessage communication methods
Analysis report on China's photovoltaic inverter market prospect forecast and investment strategy recommendations in 2022
Analysis report on the "fourteenth five year plan" and investment prospect of China's pharmaceutical equipment industry 2022-2028
fastjson的JSONArray和JSONObject[通俗易懂]
Scala-day05-set
房租是由什么决定的
11、 Box styles and user interface
What are the top ten securities companies? Is it safe to open a mobile account?
Introduction to the strongest swarm cluster one click deployment + hydrogen bomb level container management tool
Current situation investigation and investment prospect forecast analysis report of China's electrolytic copper market from 2022 to 2028
Five strategies and suggestions of member marketing in consumer goods industry
PolarisMesh系列文章——概念系列(一)
KITTI Detection dataset whose format is letf_top_right_bottom to JDE normalied xc_yc_w_h
一个初级多线程服务器模型
SQL injection
MS17_ 010 utilization summary
Fengshentai old shooting range Kali series
Hello! Forward proxy!
Five problems and solutions of member operation