mirror of
https://github.com/halfrost/LeetCode-Go.git
synced 2025-07-04 16:12:47 +08:00
添加 problem 470、717、920
This commit is contained in:
@ -0,0 +1,23 @@
|
||||
package leetcode
|
||||
|
||||
import "math/rand"
|
||||
|
||||
func rand10() int {
|
||||
rand10 := 10
|
||||
for rand10 >= 10 {
|
||||
rand10 = (rand7() - 1) + rand7()
|
||||
}
|
||||
return rand10%10 + 1
|
||||
}
|
||||
|
||||
func rand7() int {
|
||||
return rand.Intn(7)
|
||||
}
|
||||
|
||||
func rand101() int {
|
||||
rand40 := 40
|
||||
for rand40 >= 40 {
|
||||
rand40 = (rand7()-1)*7 + rand7() - 1
|
||||
}
|
||||
return rand40%10 + 1
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question470 struct {
|
||||
para470
|
||||
ans470
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para470 struct {
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans470 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem470(t *testing.T) {
|
||||
|
||||
qs := []question470{
|
||||
|
||||
question470{
|
||||
para470{},
|
||||
ans470{2},
|
||||
},
|
||||
|
||||
question470{
|
||||
para470{},
|
||||
ans470{0},
|
||||
},
|
||||
|
||||
question470{
|
||||
para470{},
|
||||
ans470{1},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 470------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans470, q.para470
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, rand10())
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
69
Algorithms/0470. Implement Rand10() Using Rand7()/README.md
Executable file
69
Algorithms/0470. Implement Rand10() Using Rand7()/README.md
Executable file
@ -0,0 +1,69 @@
|
||||
# [470. Implement Rand10() Using Rand7()](https://leetcode.com/problems/implement-rand10-using-rand7/)
|
||||
|
||||
|
||||
## 题目:
|
||||
|
||||
Given a function `rand7` which generates a uniform random integer in the range 1 to 7, write a function `rand10` which generates a uniform random integer in the range 1 to 10.
|
||||
|
||||
Do NOT use system's `Math.random()`.
|
||||
|
||||
**Example 1:**
|
||||
|
||||
Input: 1
|
||||
Output: [7]
|
||||
|
||||
**Example 2:**
|
||||
|
||||
Input: 2
|
||||
Output: [8,4]
|
||||
|
||||
**Example 3:**
|
||||
|
||||
Input: 3
|
||||
Output: [8,1,10]
|
||||
|
||||
**Note:**
|
||||
|
||||
1. `rand7` is predefined.
|
||||
2. Each testcase has one argument: `n`, the number of times that `rand10` is called.
|
||||
|
||||
**Follow up:**
|
||||
|
||||
1. What is the [expected value](https://en.wikipedia.org/wiki/Expected_value) for the number of calls to `rand7()` function?
|
||||
2. Could you minimize the number of calls to `rand7()`?
|
||||
|
||||
|
||||
## 题目大意
|
||||
|
||||
已有方法 rand7 可生成 1 到 7 范围内的均匀随机整数,试写一个方法 rand10 生成 1 到 10 范围内的均匀随机整数。不要使用系统的 Math.random() 方法。
|
||||
|
||||
|
||||
提示:
|
||||
|
||||
- rand7 已定义。
|
||||
- 传入参数: n 表示 rand10 的调用次数。
|
||||
|
||||
|
||||
进阶:
|
||||
|
||||
- rand7()调用次数的 期望值 是多少 ?
|
||||
- 你能否尽量少调用 rand7() ?
|
||||
|
||||
|
||||
|
||||
## 解题思路
|
||||
|
||||
|
||||
- 给出 `rand7()` 要求实现 `rand10()`。
|
||||
- `rand7()` 等概率地产生1,2,3,4,5,6,7。要想得到 `rand10()` 即等概率的生成 1-10 。解题思路是先构造一个 `randN()`,这个 N 必须是 10 的整数倍,然后 randN % 10 就可以得到 `rand10()` 了。所以可以从 `rand7()` 先构造出 `rand49()`,再把 `rand49()` 中大于等于 40 的都过滤掉,这样就得到了 `rand40()`,在对 10 取余即可。
|
||||
- 具体构造步骤,`rand7() --> rand49() --> rand40() --> rand10()`:
|
||||
1. `rand7()` 等概率地产生 1,2,3,4,5,6,7.
|
||||
2. `rand7() - 1` 等概率地产生 [0,6].
|
||||
3. `(rand7() - 1) *7` 等概率地产生 0, 7, 14, 21, 28, 35, 42
|
||||
4. `(rand7() - 1) * 7 + (rand7() - 1)` 等概率地产生 [0, 48] 这 49 个数字
|
||||
5. 如果步骤 4 的结果大于等于 40,那么就重复步骤 4,直到产生的数小于 40
|
||||
6. 把步骤 5 的结果 mod 10 再加 1, 就会等概率的随机生成 [1, 10]
|
||||
- 这道题可以推广到生成任意数的随机数问题。用 `randN()` 实现 `randM()`,`M>N`。步骤如下:
|
||||
1. 用 `randN()` 先实现 `randX()`,其中 X ≥ M,X 是 M 的整数倍。如这题中的 49 > 10;
|
||||
2. 再用 `randX()` 生成 `randM()`,如这题中的 49 —> 40 —> 10。
|
||||
- 举个例子,用 `rand3()` 生成 `rand11()`,可以先生成 `rand27()`,然后变成以 22 为界限,因为 22 是 11 的倍数。生成 `rand27()` 的方式:`3 * 3 * (rand3() - 1) + 3 * (rand3() - 1) + (rand3() - 1)`,最后生成了 `rand11()`;用 `rand7()` 生成 `rand9()`,可以先生成 `rand49()`,然后变成以 45 为界限,因为 45 是 9 的倍数。生成 `rand49()` 的方式:`(rand7() - 1) * 7 + (rand7() - 1)`,最后生成了 `rand9()`;用 `rand6()` 生成 `rand13()`,可以先生成 `rand36()`,然后变成以 26 为界限,因为 26 是 13 的倍数。生成 `rand36()` 的方式:`(rand6() - 1) * 6 + (rand6() - 1)`,最后生成了 `rand13()`;
|
@ -0,0 +1,11 @@
|
||||
package leetcode
|
||||
|
||||
func isOneBitCharacter(bits []int) bool {
|
||||
var i int
|
||||
for i = 0; i < len(bits)-1; i++ {
|
||||
if bits[i] == 1 {
|
||||
i++
|
||||
}
|
||||
}
|
||||
return i == len(bits)-1
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question717 struct {
|
||||
para717
|
||||
ans717
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para717 struct {
|
||||
one []int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans717 struct {
|
||||
one bool
|
||||
}
|
||||
|
||||
func Test_Problem717(t *testing.T) {
|
||||
|
||||
qs := []question717{
|
||||
|
||||
question717{
|
||||
para717{[]int{1, 0, 0}},
|
||||
ans717{true},
|
||||
},
|
||||
|
||||
question717{
|
||||
para717{[]int{1, 1, 1, 0}},
|
||||
ans717{false},
|
||||
},
|
||||
|
||||
question717{
|
||||
para717{[]int{0, 1, 1, 1, 0, 0}},
|
||||
ans717{true},
|
||||
},
|
||||
|
||||
question717{
|
||||
para717{[]int{1, 1, 1, 1, 0}},
|
||||
ans717{true},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 717------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans717, q.para717
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, isOneBitCharacter(p.one))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
50
Algorithms/0717. 1-bit and 2-bit Characters/README.md
Executable file
50
Algorithms/0717. 1-bit and 2-bit Characters/README.md
Executable file
@ -0,0 +1,50 @@
|
||||
# 717. 1-bit and 2-bit Characters
|
||||
|
||||
Created Time: Jul 25, 2019 10:23 AM
|
||||
Difficulty: Easy
|
||||
Link: https://leetcode.com/problems/1-bit-and-2-bit-characters/
|
||||
Tags: Array
|
||||
|
||||
# 题目:
|
||||
|
||||
We have two special characters. The first character can be represented by one bit `0`. The second character can be represented by two bits (`10` or `11`).
|
||||
|
||||
Now given a string represented by several bits. Return whether the last character must be a one-bit character or not. The given string will always end with a zero.
|
||||
|
||||
**Example 1:**
|
||||
|
||||
Input:
|
||||
bits = [1, 0, 0]
|
||||
Output: True
|
||||
Explanation:
|
||||
The only way to decode it is two-bit character and one-bit character. So the last character is one-bit character.
|
||||
|
||||
**Example 2:**
|
||||
|
||||
Input:
|
||||
bits = [1, 1, 1, 0]
|
||||
Output: False
|
||||
Explanation:
|
||||
The only way to decode it is two-bit character and two-bit character. So the last character is NOT one-bit character.
|
||||
|
||||
**Note:**
|
||||
|
||||
- `1 <= len(bits) <= 1000`.
|
||||
- `bits[i]` is always `0` or `1`.
|
||||
|
||||
## 题目大意
|
||||
|
||||
有两种特殊字符。第一种字符可以用一比特0来表示。第二种字符可以用两比特(10 或 11)来表示。
|
||||
|
||||
现给一个由若干比特组成的字符串。问最后一个字符是否必定为一个一比特字符。给定的字符串总是由0结束。
|
||||
|
||||
注意:
|
||||
|
||||
- 1 <= len(bits) <= 1000.
|
||||
- bits[i] 总是0 或 1.
|
||||
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 给出一个数组,数组里面的元素只有 0 和 1,并且数组的最后一个元素一定是 0。有 2 种特殊的字符,第一类字符是 "0",第二类字符是 "11" 和 "10",请判断这个数组最后一个元素是否一定是属于第一类字符?
|
||||
- 依题意, 0 的来源有 2 处,可以是第一类字符,也可以是第二类字符,1 的来源只有 1 处,一定出自第二类字符。最后一个 0 当前仅当为第一类字符的情况有 2 种,第一种情况,前面出现有 0,但是 0 和 1 配对形成了第二类字符。第二种情况,前面没有出现 0 。这两种情况的共同点是除去最后一个元素,数组中前面所有的1 都“结对子”。所以利用第二类字符的特征,"1X",遍历整个数组,如果遇到 "1",就跳 2 步,因为 1 后面出现什么数字( 0 或者 1 )并不需要关心。如果 `i` 能在 `len(bits) - 1` 的地方`(数组最后一个元素)`停下,那么对应的是情况一或者情况二,前面的 0 都和 1 匹配上了,最后一个 0 一定是第一类字符。如果 `i` 在 `len(bit)` 的位置`(超出数组下标)`停下,说明 `bits[len(bits) - 1] == 1`,这个时候最后一个 0 一定属于第二类字符。
|
@ -0,0 +1,18 @@
|
||||
package leetcode
|
||||
|
||||
func numMusicPlaylists(N int, L int, K int) int {
|
||||
dp, mod := make([][]int, L+1), 1000000007
|
||||
for i := 0; i < L+1; i++ {
|
||||
dp[i] = make([]int, N+1)
|
||||
}
|
||||
dp[0][0] = 1
|
||||
for i := 1; i <= L; i++ {
|
||||
for j := 1; j <= N; j++ {
|
||||
dp[i][j] = (dp[i-1][j-1] * (N - (j - 1))) % mod
|
||||
if j > K {
|
||||
dp[i][j] = (dp[i][j] + (dp[i-1][j]*(j-K))%mod) % mod
|
||||
}
|
||||
}
|
||||
}
|
||||
return dp[L][N]
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
package leetcode
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type question920 struct {
|
||||
para920
|
||||
ans920
|
||||
}
|
||||
|
||||
// para 是参数
|
||||
// one 代表第一个参数
|
||||
type para920 struct {
|
||||
N int
|
||||
L int
|
||||
K int
|
||||
}
|
||||
|
||||
// ans 是答案
|
||||
// one 代表第一个答案
|
||||
type ans920 struct {
|
||||
one int
|
||||
}
|
||||
|
||||
func Test_Problem920(t *testing.T) {
|
||||
|
||||
qs := []question920{
|
||||
|
||||
question920{
|
||||
para920{3, 3, 1},
|
||||
ans920{6},
|
||||
},
|
||||
|
||||
question920{
|
||||
para920{2, 3, 0},
|
||||
ans920{6},
|
||||
},
|
||||
|
||||
question920{
|
||||
para920{2, 3, 1},
|
||||
ans920{2},
|
||||
},
|
||||
}
|
||||
|
||||
fmt.Printf("------------------------Leetcode Problem 920------------------------\n")
|
||||
|
||||
for _, q := range qs {
|
||||
_, p := q.ans920, q.para920
|
||||
fmt.Printf("【input】:%v 【output】:%v\n", p, numMusicPlaylists(p.N, p.L, p.K))
|
||||
}
|
||||
fmt.Printf("\n\n\n")
|
||||
}
|
59
Algorithms/0920. Number of Music Playlists/README.md
Executable file
59
Algorithms/0920. Number of Music Playlists/README.md
Executable file
@ -0,0 +1,59 @@
|
||||
# [920. Number of Music Playlists](https://leetcode.com/problems/number-of-music-playlists/)
|
||||
|
||||
|
||||
## 题目:
|
||||
|
||||
Your music player contains `N` different songs and she wants to listen to `L` ****(not necessarily different) songs during your trip. You create a playlist so that:
|
||||
|
||||
- Every song is played at least once
|
||||
- A song can only be played again only if `K` other songs have been played
|
||||
|
||||
Return the number of possible playlists. **As the answer can be very large, return it modulo `10^9 + 7`**.
|
||||
|
||||
**Example 1:**
|
||||
|
||||
Input: N = 3, L = 3, K = 1
|
||||
Output: 6
|
||||
Explanation: There are 6 possible playlists. [1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1].
|
||||
|
||||
**Example 2:**
|
||||
|
||||
Input: N = 2, L = 3, K = 0
|
||||
Output: 6
|
||||
Explanation: There are 6 possible playlists. [1, 1, 2], [1, 2, 1], [2, 1, 1], [2, 2, 1], [2, 1, 2], [1, 2, 2]
|
||||
|
||||
**Example 3:**
|
||||
|
||||
Input: N = 2, L = 3, K = 1
|
||||
Output: 2
|
||||
Explanation: There are 2 possible playlists. [1, 2, 1], [2, 1, 2]
|
||||
|
||||
**Note:**
|
||||
|
||||
1. `0 <= K < N <= L <= 100`
|
||||
|
||||
## 题目大意
|
||||
|
||||
你的音乐播放器里有 N 首不同的歌,在旅途中,你的旅伴想要听 L 首歌(不一定不同,即,允许歌曲重复)。请你为她按如下规则创建一个播放列表:
|
||||
|
||||
- 每首歌至少播放一次。
|
||||
- 一首歌只有在其他 K 首歌播放完之后才能再次播放。
|
||||
|
||||
返回可以满足要求的播放列表的数量。由于答案可能非常大,请返回它模 10^9 + 7 的结果。
|
||||
|
||||
提示:
|
||||
|
||||
- 0 <= K < N <= L <= 100
|
||||
|
||||
|
||||
|
||||
|
||||
## 解题思路
|
||||
|
||||
- 简化抽象一下题意,给 N 个数,要求从这 N 个数里面组成一个长度为 L 的序列,并且相同元素的间隔不能小于 K 个数。问总共有多少组组成方法。
|
||||
- 一拿到题,会觉得这一题是三维 DP,因为存在 3 个变量,但是实际考虑一下,可以降一维。我们先不考虑 K 的限制,只考虑 N 和 L。定义 `dp[i][j]` 代表播放列表里面有 `i` 首歌,其中包含 `j` 首不同的歌曲,那么题目要求的最终解存在 `dp[L][N]` 中。考虑 `dp[i][j]` 的递归公式,音乐列表当前需要组成 `i` 首歌,有 2 种方式可以得到,由 `i - 1` 首歌的列表中添加一首列表中**不存在**的新歌曲,或者由 `i - 1` 首歌的列表中添加一首列表中**已经存在**的歌曲。即,`dp[i][j]` 可以由 `dp[i - 1][j - 1]` 得到,也可以由 `dp[i - 1][j]` 得到。如果是第一种情况,添加一首新歌,那么新歌有 N - ( j - 1 ) 首,如果是第二种情况,添加一首已经存在的歌,歌有 j 首,所以状态转移方程是 `dp[i][j] = dp[i - 1][j - 1] * ( N - ( j - 1 ) ) + dp[i - 1][j] * j` 。但是这个方程是在不考虑 K 的限制条件下得到的,距离满足题意还差一步。接下来需要考虑加入 K 这个限制条件以后,状态转移方程该如何推导。
|
||||
- 如果是添加一首新歌,是不受 K 限制的,所以 `dp[i - 1][j - 1] * ( N - ( j - 1 ) )` 这里不需要变化。如果是添加一首存在的歌曲,这个时候就会受到 K 的限制了。如果当前播放列表里面的歌曲有 `j` 首,并且 `j > K`,那么选择歌曲只能从 `j - K` 里面选,因为不能选择 `j - 1` 到 `j - k` 的这些歌,选择了就不满足重复的歌之间间隔不能小于 `K` 的限制条件了。那 j ≤ K 呢?这个时候一首歌都不能选,因为歌曲数都没有超过 K,当然不能再选择重复的歌曲。(选择了就再次不满足重复的歌之间间隔不能小于 `K` 的限制条件了)。经过上述分析,可以得到最终的状态转移方程:
|
||||
|
||||
$$dp[i][j]=\left\{ \begin{array}{rcl} dp[i - 1][j - 1] * ( N - ( j - 1 ) ) + dp[i - 1][j] * ( j - k ) & & {j > k}\\ dp[i - 1][j - 1] * ( N - ( j - 1 ) ) & & {j \leq k}\\ \end{array} \right.$$
|
||||
|
||||
- 当 j > K 的时候,`dp[i][j] = dp[i - 1][j - 1] * (N - (j - 1)) + dp[i - 1][j] * (j - k)`;当 j ≤ K 的时候,`dp[i][j] = dp[i - 1][j - 1] * (N - (j - 1))`。递归初始值 `dp[0][0] = 1`。
|
Reference in New Issue
Block a user