Skip to content

Commit

Permalink
✨update: Modify 710
Browse files Browse the repository at this point in the history
  • Loading branch information
SharingSource committed Jun 27, 2022
1 parent 705f20d commit 290f708
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 1 deletion.
1 change: 1 addition & 0 deletions Index/哈希表.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
| [697. 数组的度](https://leetcode-cn.com/problems/degree-of-an-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/degree-of-an-array/solution/shu-zu-ji-shu-ha-xi-biao-ji-shu-jie-fa-y-a0mg/) | 简单 | 🤩🤩🤩 |
| [705. 设计哈希集合](https://leetcode-cn.com/problems/design-hashset/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/design-hashset/solution/yi-ti-san-jie-jian-dan-shu-zu-lian-biao-nj3dg/) | 简单 | 🤩🤩🤩🤩 |
| [706. 设计哈希映射](https://leetcode-cn.com/problems/design-hashmap/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/design-hashmap/solution/yi-ti-shuang-jie-jian-dan-shu-zu-lian-bi-yhiw/) | 简单 | 🤩🤩🤩🤩 |
| [710. 黑名单中的随机数](https://leetcode.cn/problems/random-pick-with-blacklist/) | [LeetCode 题解链接](https://leetcode.cn/problems/random-pick-with-blacklist/solution/by-ac_oier-2rww/) | 困难 | 🤩🤩🤩🤩 |
| [726. 原子的数量](https://leetcode-cn.com/problems/number-of-atoms/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/number-of-atoms/solution/gong-shui-san-xie-shi-yong-xiao-ji-qiao-l5ak4/) | 困难 | 🤩🤩🤩🤩 |
| [728. 自除数](https://leetcode-cn.com/problems/self-dividing-numbers/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/self-dividing-numbers/solution/by-ac_oier-pvb1/) | 简单 | 🤩🤩🤩 |
| [846. 一手顺子](https://leetcode-cn.com/problems/hand-of-straights/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/hand-of-straights/solution/gong-shui-san-xie-shu-ju-jie-gou-mo-ni-t-4hxw/) | 中等 | 🤩🤩🤩 |
Expand Down
47 changes: 46 additions & 1 deletion LeetCode/701-710/710. 黑名单中的随机数(困难).md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

这是 LeetCode 上的 **[710. 黑名单中的随机数](https://leetcode.cn/problems/random-pick-with-blacklist/solution/by-ac_oier-2rww/)** ,难度为 **困难**

Tag : 「前缀和」、「二分」、「离散化」、「随机化」
Tag : 「前缀和」、「二分」、「离散化」、「随机化」、「哈希表」



Expand Down Expand Up @@ -111,6 +111,51 @@ class Solution {

---

### 哈希表

总共有 $n$ 个数,其中 $m$ 个数不可被选,即真实可选个数为 $n - m$ 个。

为了能够在 $[0, n - m)$ 连续段内进行随机,我们可以将 $[0, n - m)$ 内不可被选的数映射到 $[n - m, n - 1]$ 内可选的数上。

具体的,我们可以使用两个 `Set` 结构 `s1``s2` 分别记录在 $[0, n - m)$ 和 $[n - m, n - 1]$ 范围内的黑名单数字。

`pick` 操作时,我们在 $[0, n - m)$ 范围内进行随机,根据随机值 $val$ 是否为黑名单内数字(是否在 `s1` 中)进行分情况讨论:

* 随机值 `val` 不在 `s1` 中,说明 `val` 是真实可选的数值,直接返回;
* 随机值 `val``s1` 中,说明 `val` 是黑名单内的数值,我们先查询是否已存在 `val` 的映射记录,若已存在直接返回其映射值;否则需要在 $[n - m, n - 1]$ 内找到一个可替代它的数值,我们可以使用一个变量 `idx` 在 $[n- m, n - 1]$ 范围内从前往后扫描,找到第一个未被使用的,同时不在 `s2` 中(不在黑名单内)的数字,假设找到的值为 `x`,将 `x` 进行返回(同时将 `val``x` 的映射关系,用哈希表进行记录)。

代码:
```Java
class Solution {
int n, m, idx;
Random random = new Random();
Set<Integer> s1 = new HashSet<>(), s2 = new HashSet<>();
Map<Integer, Integer> map = new HashMap<>();
public Solution(int _n, int[] bs) {
n = _n; m = bs.length;
int max = n - m;
for (int x : bs) {
if (x < max) s1.add(x);
else s2.add(x);
}
idx = n - m;
}
public int pick() {
int val = random.nextInt(n - m);
if (!s1.contains(val)) return val;
if (!map.containsKey(val)) {
while (s2.contains(idx)) idx++;
map.put(val, idx++);
}
return map.get(val);
}
}
```
* 时间复杂度:初始化操作复杂度为 $O(m)$,`pick` 操作复杂度为 $O(1)$
* 空间复杂度:$O(m)$

---

### 最后

这是我们「刷穿 LeetCode」系列文章的第 `No.710` 篇,系列开始于 2021/01/01,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
Expand Down

0 comments on commit 290f708

Please sign in to comment.