Skip to content

Commit 7336a99

Browse files
author
robot
committed
feat: $324, $710
1 parent 61cf965 commit 7336a99

File tree

4 files changed

+238
-1
lines changed

4 files changed

+238
-1
lines changed

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,7 @@ leetcode 题解,记录自己的 leetcode 解题之路。
329329
- [0279. 完全平方数](./problems/279.perfect-squares.md)
330330
- [0309. 最佳买卖股票时机含冷冻期](./problems/309.best-time-to-buy-and-sell-stock-with-cooldown.md)
331331
- [0322. 零钱兑换](./problems/322.coin-change.md) 👍
332+
- [0324. 摆动排序 II](./problems/324.wiggle-sort-ii.md)
332333
- [0328. 奇偶链表](./problems/328.odd-even-linked-list.md)
333334
- [0331. 验证二叉树的前序序列化](./problems/331.verify-preorder-serialization-of-a-binary-tree.md)
334335
- [0334. 递增的三元子序列](./problems/334.increasing-triplet-subsequence.md)
@@ -360,8 +361,9 @@ leetcode 题解,记录自己的 leetcode 解题之路。
360361
- [0611. 有效三角形的个数](./problems/611.valid-triangle-number.md) 👍
361362
- [0673. 最长递增子序列的个数](./problems/673.number-of-longest-increasing-subsequence.md)
362363
- [0686. 重复叠加字符串匹配](./problems/686.repeated-string-match.md)
363-
- [0718. 最长重复子数组](./problems/718.maximum-length-of-repeated-subarray.md)
364+
- [0710. 黑名单中的随机数](./problems/710.random-pick-with-blacklist.md)
364365
- [0714. 买卖股票的最佳时机含手续费](./problems/714.best-time-to-buy-and-sell-stock-with-transaction-fee.md)
366+
- [0718. 最长重复子数组](./problems/718.maximum-length-of-repeated-subarray.md)
365367
- [0735. 行星碰撞](./problems/735.asteroid-collision.md) 👍
366368
- [0754. 到达终点数字](./problems/754.reach-a-number.md)
367369
- [0785. 判断二分图](./problems/785.is-graph-bipartite.md)

SUMMARY.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@
174174
- [0279. 完全平方数](./problems/279.perfect-squares.md)
175175
- [0309. 最佳买卖股票时机含冷冻期](./problems/309.best-time-to-buy-and-sell-stock-with-cooldown.md) 👍
176176
- [0322. 零钱兑换](./problems/322.coin-change.md)
177+
- [0324. 摆动排序 II](./problems/324.wiggle-sort-ii.md)
177178
- [0328. 奇偶链表](./problems/328.odd-even-linked-list.md)
178179
- [0331. 验证二叉树的前序序列化](./problems/331.verify-preorder-serialization-of-a-binary-tree.md) 👍
179180
- [0334. 递增的三元子序列](./problems/334.increasing-triplet-subsequence.md) 👍
@@ -204,6 +205,7 @@
204205
- [0611. 有效三角形的个数](./problems/611.valid-triangle-number.md) 👍
205206
- [0673. 最长递增子序列的个数](./problems/673.number-of-longest-increasing-subsequence.md)
206207
- [0686. 重复叠加字符串匹配](./problems/686.repeated-string-match.md)
208+
- [0710. 黑名单中的随机数](./problems/710.random-pick-with-blacklist.md)
207209
- [0714. 买卖股票的最佳时机含手续费](./problems/714.best-time-to-buy-and-sell-stock-with-transaction-fee.md) 👍
208210
- [0718. 最长重复子数组](./problems/718.maximum-length-of-repeated-subarray.md)
209211
- [0735. 行星碰撞](./problems/735.asteroid-collision.md)

problems/324.wiggle-sort-ii.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
## 题目地址(324. 摆动排序 II)
2+
3+
https://leetcode.cn/problems/wiggle-sort-ii/
4+
5+
## 题目描述
6+
7+
```
8+
给你一个整数数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]... 的顺序。
9+
10+
你可以假设所有输入数组都可以得到满足题目要求的结果。
11+
12+
 
13+
14+
示例 1:
15+
16+
输入:nums = [1,5,1,1,6,4]
17+
输出:[1,6,1,5,1,4]
18+
解释:[1,4,1,5,1,6] 同样是符合题目要求的结果,可以被判题程序接受。
19+
20+
21+
示例 2:
22+
23+
输入:nums = [1,3,2,2,3,1]
24+
输出:[2,3,1,3,1,2]
25+
26+
27+
 
28+
29+
提示:
30+
31+
1 <= nums.length <= 5 * 104
32+
0 <= nums[i] <= 5000
33+
题目数据保证,对于给定的输入 nums ,总能产生满足题目要求的结果
34+
35+
 
36+
37+
进阶:你能用 O(n) 时间复杂度和 / 或原地 O(1) 额外空间来实现吗?
38+
```
39+
40+
## 前置知识
41+
42+
-
43+
44+
## 公司
45+
46+
- 暂无
47+
48+
## 思路
49+
50+
这是一道构造题目,一般来说构造题目的难度都偏大一点,这一道题目也不例外,尤其是进阶。关于进阶不在这里展开,因为[题解区](https://leetcode.cn/problems/wiggle-sort-ii/solution/)给出了很多优秀的解法了。
51+
52+
这道题让我们重新排 nums, 使得奇数索引的数都比相邻的偶数索引大。
53+
54+
我们可以先进行一次倒序排序。接下来先从小到大给奇数索引放置数字,然后再次从小到大给偶数索引放置数字即可。
55+
56+
> 这里的从小到大指的是索引值从小到大,即先放索引较小的,再放索引较大的。
57+
58+
为什么可行?
59+
60+
因为我们是倒序排序的,因此后放置的偶数索引一定是不大于奇数索引的。但是能够保证严格小于相邻的奇数索引么?
61+
62+
由于题目保证了有解。因此实际上按照这种放置方法可以,但是如果:先从小到大给奇数索引放置数字,然后再次从大到小给偶数索引放置数字。那么就有可能无解。无解的情况是数组中有大量的相同数字。但是题目保证有解的情况,**先从小到大给奇数索引放置数字,然后再次从小到大给偶数索引放置数字** 是不会有问题的。
63+
64+
## 关键点
65+
66+
- 排序后按照奇偶性分别放置
67+
68+
## 代码
69+
70+
- 语言支持:Python3
71+
72+
Python3 Code:
73+
74+
```python
75+
76+
class Solution:
77+
def wiggleSort(self, nums: List[int]) -> None:
78+
"""
79+
Do not return anything, modify nums in-place instead.
80+
"""
81+
n = len(nums)
82+
s = sorted(nums, reverse=True)
83+
84+
i = 1
85+
j = 0
86+
while i < n:
87+
nums[i] = s[j]
88+
i += 2
89+
j += 1
90+
i = 0
91+
while i < n:
92+
nums[i] = s[j]
93+
i += 2
94+
j += 1
95+
96+
```
97+
98+
**复杂度分析**
99+
100+
令 n 为数组长度。
101+
102+
- 时间复杂度:$O(nlogn)$ 主要是排序
103+
- 空间复杂度:$O(n)$ 拷贝了一个新的数组 s
104+
105+
> 此题解由 [力扣刷题插件](https://leetcode-pp.github.io/leetcode-cheat/?tab=solution-template) 自动生成。
106+
107+
力扣的小伙伴可以[关注我](https://leetcode-cn.com/u/fe-lucifer/),这样就会第一时间收到我的动态啦~
108+
109+
以上就是本文的全部内容了。大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 40K star 啦。大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。
110+
111+
关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。
112+
113+
![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfcuzagjalj30p00dwabs.jpg)
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
## 题目地址(710. 黑名单中的随机数)
2+
3+
https://leetcode.cn/problems/random-pick-with-blacklist/
4+
5+
## 题目描述
6+
7+
```
8+
给定一个整数 n 和一个 无重复 黑名单整数数组 blacklist 。设计一种算法,从 [0, n - 1] 范围内的任意整数中选取一个 未加入 黑名单 blacklist 的整数。任何在上述范围内且不在黑名单 blacklist 中的整数都应该有 同等的可能性 被返回。
9+
10+
优化你的算法,使它最小化调用语言 内置 随机函数的次数。
11+
12+
实现 Solution 类:
13+
14+
Solution(int n, int[] blacklist) 初始化整数 n 和被加入黑名单 blacklist 的整数
15+
int pick() 返回一个范围为 [0, n - 1] 且不在黑名单 blacklist 中的随机整数
16+
17+
 
18+
19+
示例 1:
20+
21+
输入
22+
["Solution", "pick", "pick", "pick", "pick", "pick", "pick", "pick"]
23+
[[7, [2, 3, 5]], [], [], [], [], [], [], []]
24+
输出
25+
[null, 0, 4, 1, 6, 1, 0, 4]
26+
27+
解释
28+
Solution solution = new Solution(7, [2, 3, 5]);
29+
solution.pick(); // 返回0,任何[0,1,4,6]的整数都可以。注意,对于每一个pick的调用,
30+
// 0、1、4和6的返回概率必须相等(即概率为1/4)。
31+
solution.pick(); // 返回 4
32+
solution.pick(); // 返回 1
33+
solution.pick(); // 返回 6
34+
solution.pick(); // 返回 1
35+
solution.pick(); // 返回 0
36+
solution.pick(); // 返回 4
37+
38+
39+
 
40+
41+
提示:
42+
43+
1 <= n <= 109
44+
0 <= blacklist.length <= min(105, n - 1)
45+
0 <= blacklist[i] < n
46+
blacklist 中所有值都 不同
47+
 pick 最多被调用 2 * 104 次
48+
```
49+
50+
## 前置知识
51+
52+
- 哈希表
53+
- 概率
54+
55+
## 公司
56+
57+
- 暂无
58+
59+
## 思路
60+
61+
题目让我们从 [0, n-1] 随机选一个数,且要求不能是在 blacklist 中,且要求所有数被选中的概率相等。
62+
63+
也就是说我们可以选择的数字的个数为 n - m,其中 m 为 blacklist 的长度。我们需要在这 n - m 中选择一个随机的数,每个数被选中的记录都是 1/(n-m)。
64+
65+
我们可以随机一个 [0, n-m-1] 的数字。
66+
67+
- 如果这个数不在黑名单,直接返回即可。 不难得出,此时的概率是 1/(n-m),符合题意
68+
- 如果这个数在黑名单。我们不能返回,那么我们可以将其转化为一个白名单的数。 由于黑名单一共有 m 个,假设在 [0,n-m-1]范围内的黑名单有 x 个,那么[n-m+1,n-1] 范围的黑名单就是 m - x,同时在 [n-m+1,n-1] 范围的白名单就是 x。那么其实选中的是黑名单的数的概率就是 x/(n-m),我们随机找 [n-m+1,n-1] 范围的白名单概率是 1/x。二者相乘就是映射到的白名单中的数被选中的概率,即 1/(n-m)
69+
70+
综上,我们可以使用哈希表 b2w 维护这种映射关系。其中 key 为 [0,n-m-1] 中的黑名单中的数,value 为随机找的一个 [n-m, n-1] 的白名单中的数。
71+
72+
具体实现看代码。
73+
74+
## 关键点
75+
76+
- 将黑名单中的数字映射到白名单
77+
78+
## 代码
79+
80+
- 语言支持:Python3
81+
82+
Python3 Code:
83+
84+
```python
85+
86+
class Solution:
87+
def __init__(self, n: int, blacklist: List[int]):
88+
m = len(blacklist)
89+
self.bound = w = n - m
90+
black = {b for b in blacklist if b >= self.bound}
91+
self.b2w = {}
92+
for b in blacklist:
93+
if b < self.bound:
94+
while w in black:
95+
w += 1
96+
self.b2w[b] = w
97+
w += 1
98+
99+
def pick(self) -> int:
100+
x = randrange(self.bound)
101+
return self.b2w.get(x, x)
102+
103+
```
104+
105+
**复杂度分析**
106+
107+
令 n 为 blacklist 长度。
108+
109+
- 时间复杂度:$O(n)$
110+
- 空间复杂度:$O(n)$
111+
112+
> 此题解由 [力扣刷题插件](https://leetcode-pp.github.io/leetcode-cheat/?tab=solution-template) 自动生成。
113+
114+
力扣的小伙伴可以[关注我](https://leetcode-cn.com/u/fe-lucifer/),这样就会第一时间收到我的动态啦~
115+
116+
以上就是本文的全部内容了。大家对此有何看法,欢迎给我留言,我有时间都会一一查看回答。更多算法套路可以访问我的 LeetCode 题解仓库:https://github.com/azl397985856/leetcode 。 目前已经 40K star 啦。大家也可以关注我的公众号《力扣加加》带你啃下算法这块硬骨头。
117+
118+
关注公众号力扣加加,努力用清晰直白的语言还原解题思路,并且有大量图解,手把手教你识别套路,高效刷题。
119+
120+
![](https://tva1.sinaimg.cn/large/007S8ZIlly1gfcuzagjalj30p00dwabs.jpg)

0 commit comments

Comments
 (0)