Skip to content

Commit 153e4f4

Browse files
authored
Merge branch 'doocs:main' into main
2 parents fc9a143 + 2f350d9 commit 153e4f4

File tree

160 files changed

+6741
-2098
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

160 files changed

+6741
-2098
lines changed

.github/workflows/pr-add-label.yml

Lines changed: 0 additions & 28 deletions
This file was deleted.

solution/0300-0399/0355.Design Twitter/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ twitter.getNewsFeed(1); // 用户 1 获取推文应当返回一个列表,其
6161
<li><code>0 &lt;= tweetId &lt;= 10<sup>4</sup></code></li>
6262
<li>所有推特的 ID 都互不相同</li>
6363
<li><code>postTweet</code>、<code>getNewsFeed</code>、<code>follow</code> 和 <code>unfollow</code> 方法最多调用 <code>3 * 10<sup>4</sup></code> 次</li>
64+
<li>用户不能关注自己</li>
6465
</ul>
6566

6667
<!-- description:end -->

solution/0300-0399/0355.Design Twitter/README_EN.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ twitter.getNewsFeed(1); // User 1&#39;s news feed should return a list with 1 t
6060
<li><code>0 &lt;= tweetId &lt;= 10<sup>4</sup></code></li>
6161
<li>All the tweets have <strong>unique</strong> IDs.</li>
6262
<li>At most <code>3 * 10<sup>4</sup></code> calls will be made to <code>postTweet</code>, <code>getNewsFeed</code>, <code>follow</code>, and <code>unfollow</code>.</li>
63+
<li>A user cannot follow himself.</li>
6364
</ul>
6465

6566
<!-- description:end -->

solution/0600-0699/0688.Knight Probability in Chessboard/README.md

Lines changed: 29 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,19 @@ tags:
6565

6666
### 方法一:动态规划
6767

68-
我们定义 $f[h][i][j]$ 表示骑士从 $(i, j)$ 位置出发,走了 $h$ 步以后还留在棋盘上的概率。那么最终答案就是 $f[k][row][column]$。
68+
我们定义 $f[h][i][j]$ 表示骑士从 $(i, j)$ 位置出发,走了 $h$ 步以后还留在棋盘上的概率。那么最终答案就是 $f[k][\textit{row}][\textit{column}]$。
6969

7070
当 $h=0$ 时,骑士一定在棋盘上,概率为 $1$,即 $f[0][i][j]=1$。
7171

7272
当 $h \gt 0$ 时,骑士在 $(i, j)$ 位置上的概率可以由其上一步的 $8$ 个位置上的概率转移得到,即:
7373

7474
$$
75-
f[h][i][j] = \sum_{a, b} f[h - 1][a][b] \times \frac{1}{8}
75+
f[h][i][j] = \sum_{x, y} f[h - 1][x][y] \times \frac{1}{8}
7676
$$
7777

78-
其中 $(a, b)$ 是从 $(i, j)$ 位置可以走到的 $8$ 个位置中的一个。
78+
其中 $(x, y)$ 是从 $(i, j)$ 位置可以走到的 $8$ 个位置中的一个。
7979

80-
最终答案即为 $f[k][row][column]$。
80+
最终答案即为 $f[k][\textit{row}][\textit{column}]$。
8181

8282
时间复杂度 $O(k \times n^2)$,空间复杂度 $O(k \times n^2)$。其中 $k$ 和 $n$ 分别是给定的步数和棋盘大小。
8383

@@ -197,9 +197,9 @@ func knightProbability(n int, k int, row int, column int) float64 {
197197

198198
```ts
199199
function knightProbability(n: number, k: number, row: number, column: number): number {
200-
const f = new Array(k + 1)
201-
.fill(0)
202-
.map(() => new Array(n).fill(0).map(() => new Array(n).fill(0)));
200+
const f = Array.from({ length: k + 1 }, () =>
201+
Array.from({ length: n }, () => Array(n).fill(0)),
202+
);
203203
for (let i = 0; i < n; ++i) {
204204
for (let j = 0; j < n; ++j) {
205205
f[0][i][j] = 1;
@@ -226,55 +226,39 @@ function knightProbability(n: number, k: number, row: number, column: number): n
226226
#### Rust
227227

228228
```rust
229-
const DIR: [(i32, i32); 8] = [
230-
(-2, -1),
231-
(2, -1),
232-
(-1, -2),
233-
(1, -2),
234-
(2, 1),
235-
(-2, 1),
236-
(1, 2),
237-
(-1, 2),
238-
];
239-
const P: f64 = 1.0 / 8.0;
240-
241229
impl Solution {
242-
#[allow(dead_code)]
243230
pub fn knight_probability(n: i32, k: i32, row: i32, column: i32) -> f64 {
244-
// Here dp[i][j][k] represents through `i` steps, the probability that the knight stays on the board
245-
// Starts from row: `j`, column: `k`
246-
let mut dp: Vec<Vec<Vec<f64>>> =
247-
vec![vec![vec![0 as f64; n as usize]; n as usize]; k as usize + 1];
248-
249-
// Initialize the dp vector, since dp[0][j][k] should be 1
250-
for j in 0..n as usize {
251-
for k in 0..n as usize {
252-
dp[0][j][k] = 1.0;
231+
let n = n as usize;
232+
let k = k as usize;
233+
234+
let mut f = vec![vec![vec![0.0; n]; n]; k + 1];
235+
236+
for i in 0..n {
237+
for j in 0..n {
238+
f[0][i][j] = 1.0;
253239
}
254240
}
255241

256-
// Begin the actual dp process
257-
for i in 1..=k {
258-
for j in 0..n {
259-
for k in 0..n {
260-
for (dx, dy) in DIR {
261-
let x = j + dx;
262-
let y = k + dy;
263-
if Self::check_bounds(x, y, n, n) {
264-
dp[i as usize][j as usize][k as usize] +=
265-
P * dp[(i as usize) - 1][x as usize][y as usize];
242+
let dirs = [-2, -1, 2, 1, -2, 1, 2, -1, -2];
243+
244+
for h in 1..=k {
245+
for i in 0..n {
246+
for j in 0..n {
247+
for p in 0..8 {
248+
let x = i as isize + dirs[p];
249+
let y = j as isize + dirs[p + 1];
250+
251+
if x >= 0 && x < n as isize && y >= 0 && y < n as isize {
252+
let x = x as usize;
253+
let y = y as usize;
254+
f[h][i][j] += f[h - 1][x][y] / 8.0;
266255
}
267256
}
268257
}
269258
}
270259
}
271260

272-
dp[k as usize][row as usize][column as usize]
273-
}
274-
275-
#[allow(dead_code)]
276-
fn check_bounds(i: i32, j: i32, n: i32, m: i32) -> bool {
277-
i >= 0 && i < n && j >= 0 && j < m
261+
f[k][row as usize][column as usize]
278262
}
279263
}
280264
```

solution/0600-0699/0688.Knight Probability in Chessboard/README_EN.md

Lines changed: 32 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -61,21 +61,21 @@ The total probability the knight stays on the board is 0.0625.
6161

6262
### Solution 1: Dynamic Programming
6363

64-
Let $f[h][i][j]$ denotes the probability that the knight is still on the chessboard after $h$ steps starting from the position $(i, j)$. Then the final answer is $f[k][row][column]$.
64+
We define $f[h][i][j]$ to represent the probability that the knight remains on the board after taking $h$ steps starting from position $(i, j)$. The final answer is $f[k][\textit{row}][\textit{column}]$.
6565

66-
When $h = 0$, the knight is always on the chessboard, so $f[0][i][j] = 1$.
66+
When $h=0$, the knight is definitely on the board, so the probability is $1$, i.e., $f[0][i][j]=1$.
6767

68-
When $h \gt 0$, the probability that the knight is on the position $(i, j)$ can be transferred from the probability on its $8$ adjacent positions, which are:
68+
When $h \gt 0$, the probability that the knight is at position $(i, j)$ can be derived from the probabilities of the $8$ possible positions it could have come from in the previous step, i.e.,
6969

7070
$$
71-
f[h][i][j] = \sum_{a, b} f[h - 1][a][b] \times \frac{1}{8}
71+
f[h][i][j] = \sum_{x, y} f[h - 1][x][y] \times \frac{1}{8}
7272
$$
7373

74-
where $(a, b)$ is one of the $8$ adjacent positions.
74+
where $(x, y)$ is one of the $8$ positions the knight can move to from $(i, j)$.
7575

76-
The final answer is $f[k][row][column]$.
76+
The final answer is $f[k][\textit{row}][\textit{column}]$.
7777

78-
The time complexity is $O(k \times n^2)$, and the space complexity is $O(k \times n^2)$. Here $k$ and $n$ are the given steps and the chessboard size, respectively.
78+
The time complexity is $O(k \times n^2)$, and the space complexity is $O(k \times n^2)$. Here, $k$ and $n$ are the given number of steps and the size of the board, respectively.
7979

8080
<!-- tabs:start -->
8181

@@ -193,9 +193,9 @@ func knightProbability(n int, k int, row int, column int) float64 {
193193

194194
```ts
195195
function knightProbability(n: number, k: number, row: number, column: number): number {
196-
const f = new Array(k + 1)
197-
.fill(0)
198-
.map(() => new Array(n).fill(0).map(() => new Array(n).fill(0)));
196+
const f = Array.from({ length: k + 1 }, () =>
197+
Array.from({ length: n }, () => Array(n).fill(0)),
198+
);
199199
for (let i = 0; i < n; ++i) {
200200
for (let j = 0; j < n; ++j) {
201201
f[0][i][j] = 1;
@@ -222,55 +222,39 @@ function knightProbability(n: number, k: number, row: number, column: number): n
222222
#### Rust
223223

224224
```rust
225-
const DIR: [(i32, i32); 8] = [
226-
(-2, -1),
227-
(2, -1),
228-
(-1, -2),
229-
(1, -2),
230-
(2, 1),
231-
(-2, 1),
232-
(1, 2),
233-
(-1, 2),
234-
];
235-
const P: f64 = 1.0 / 8.0;
236-
237225
impl Solution {
238-
#[allow(dead_code)]
239226
pub fn knight_probability(n: i32, k: i32, row: i32, column: i32) -> f64 {
240-
// Here dp[i][j][k] represents through `i` steps, the probability that the knight stays on the board
241-
// Starts from row: `j`, column: `k`
242-
let mut dp: Vec<Vec<Vec<f64>>> =
243-
vec![vec![vec![0 as f64; n as usize]; n as usize]; k as usize + 1];
244-
245-
// Initialize the dp vector, since dp[0][j][k] should be 1
246-
for j in 0..n as usize {
247-
for k in 0..n as usize {
248-
dp[0][j][k] = 1.0;
227+
let n = n as usize;
228+
let k = k as usize;
229+
230+
let mut f = vec![vec![vec![0.0; n]; n]; k + 1];
231+
232+
for i in 0..n {
233+
for j in 0..n {
234+
f[0][i][j] = 1.0;
249235
}
250236
}
251237

252-
// Begin the actual dp process
253-
for i in 1..=k {
254-
for j in 0..n {
255-
for k in 0..n {
256-
for (dx, dy) in DIR {
257-
let x = j + dx;
258-
let y = k + dy;
259-
if Self::check_bounds(x, y, n, n) {
260-
dp[i as usize][j as usize][k as usize] +=
261-
P * dp[(i as usize) - 1][x as usize][y as usize];
238+
let dirs = [-2, -1, 2, 1, -2, 1, 2, -1, -2];
239+
240+
for h in 1..=k {
241+
for i in 0..n {
242+
for j in 0..n {
243+
for p in 0..8 {
244+
let x = i as isize + dirs[p];
245+
let y = j as isize + dirs[p + 1];
246+
247+
if x >= 0 && x < n as isize && y >= 0 && y < n as isize {
248+
let x = x as usize;
249+
let y = y as usize;
250+
f[h][i][j] += f[h - 1][x][y] / 8.0;
262251
}
263252
}
264253
}
265254
}
266255
}
267256

268-
dp[k as usize][row as usize][column as usize]
269-
}
270-
271-
#[allow(dead_code)]
272-
fn check_bounds(i: i32, j: i32, n: i32, m: i32) -> bool {
273-
i >= 0 && i < n && j >= 0 && j < m
257+
f[k][row as usize][column as usize]
274258
}
275259
}
276260
```
Lines changed: 21 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,35 @@
1-
const DIR: [(i32, i32); 8] = [
2-
(-2, -1),
3-
(2, -1),
4-
(-1, -2),
5-
(1, -2),
6-
(2, 1),
7-
(-2, 1),
8-
(1, 2),
9-
(-1, 2),
10-
];
11-
const P: f64 = 1.0 / 8.0;
12-
131
impl Solution {
14-
#[allow(dead_code)]
152
pub fn knight_probability(n: i32, k: i32, row: i32, column: i32) -> f64 {
16-
// Here dp[i][j][k] represents through `i` steps, the probability that the knight stays on the board
17-
// Starts from row: `j`, column: `k`
18-
let mut dp: Vec<Vec<Vec<f64>>> =
19-
vec![vec![vec![0 as f64; n as usize]; n as usize]; k as usize + 1];
3+
let n = n as usize;
4+
let k = k as usize;
5+
6+
let mut f = vec![vec![vec![0.0; n]; n]; k + 1];
207

21-
// Initialize the dp vector, since dp[0][j][k] should be 1
22-
for j in 0..n as usize {
23-
for k in 0..n as usize {
24-
dp[0][j][k] = 1.0;
8+
for i in 0..n {
9+
for j in 0..n {
10+
f[0][i][j] = 1.0;
2511
}
2612
}
2713

28-
// Begin the actual dp process
29-
for i in 1..=k {
30-
for j in 0..n {
31-
for k in 0..n {
32-
for (dx, dy) in DIR {
33-
let x = j + dx;
34-
let y = k + dy;
35-
if Self::check_bounds(x, y, n, n) {
36-
dp[i as usize][j as usize][k as usize] +=
37-
P * dp[(i as usize) - 1][x as usize][y as usize];
14+
let dirs = [-2, -1, 2, 1, -2, 1, 2, -1, -2];
15+
16+
for h in 1..=k {
17+
for i in 0..n {
18+
for j in 0..n {
19+
for p in 0..8 {
20+
let x = i as isize + dirs[p];
21+
let y = j as isize + dirs[p + 1];
22+
23+
if x >= 0 && x < n as isize && y >= 0 && y < n as isize {
24+
let x = x as usize;
25+
let y = y as usize;
26+
f[h][i][j] += f[h - 1][x][y] / 8.0;
3827
}
3928
}
4029
}
4130
}
4231
}
4332

44-
dp[k as usize][row as usize][column as usize]
45-
}
46-
47-
#[allow(dead_code)]
48-
fn check_bounds(i: i32, j: i32, n: i32, m: i32) -> bool {
49-
i >= 0 && i < n && j >= 0 && j < m
33+
f[k][row as usize][column as usize]
5034
}
5135
}

solution/0600-0699/0688.Knight Probability in Chessboard/Solution.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
function knightProbability(n: number, k: number, row: number, column: number): number {
2-
const f = new Array(k + 1)
3-
.fill(0)
4-
.map(() => new Array(n).fill(0).map(() => new Array(n).fill(0)));
2+
const f = Array.from({ length: k + 1 }, () =>
3+
Array.from({ length: n }, () => Array(n).fill(0)),
4+
);
55
for (let i = 0; i < n; ++i) {
66
for (let j = 0; j < n; ++j) {
77
f[0][i][j] = 1;

solution/0700-0799/0782.Transform to Chessboard/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ tags:
9393

9494
若 $n$ 为奇数,那么最终的合法棋盘只有一种可能。如果第一行中 $0$ 的数目大于 $1$,那么最终一盘的第一行只能是“01010...”,否则就是“10101...”。同样算出次数作为答案。
9595

96-
时间复杂度 $O(n^2)$。
96+
时间复杂度 $O(n^2)$,其中 $n$ 是棋盘的大小。空间复杂度 $O(1)$
9797

9898
<!-- tabs:start -->
9999

solution/0700-0799/0782.Transform to Chessboard/README_EN.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,24 @@ The second move swaps the second and third row.
6868

6969
<!-- solution:start -->
7070

71-
### Solution 1
71+
### Solution 1: Pattern Observation + State Compression
72+
73+
In a valid chessboard, there are exactly two types of "rows".
74+
75+
For example, if one row on the chessboard is "01010011", then any other row can only be "01010011" or "10101100". Columns also satisfy this property.
76+
77+
Additionally, each row and each column has half $0$s and half $1$s. Suppose the chessboard is $n \times n$:
78+
79+
- If $n = 2 \times k$, then each row and each column has $k$ $1$s and $k$ $0$s.
80+
- If $n = 2 \times k + 1$, then each row has $k$ $1$s and $k + 1$ $0$s, or $k + 1$ $1$s and $k$ $0$s.
81+
82+
Based on the above conclusions, we can determine whether a chessboard is valid. If valid, we can calculate the minimum number of moves required.
83+
84+
If $n$ is even, there are two possible valid chessboards, where the first row is either "010101..." or "101010...". We calculate the minimum number of swaps required for these two possibilities and take the smaller value as the answer.
85+
86+
If $n$ is odd, there is only one possible valid chessboard. If the number of $0$s in the first row is greater than the number of $1$s, then the first row of the final chessboard must be "01010..."; otherwise, it must be "10101...". We calculate the number of swaps required and use it as the answer.
87+
88+
The time complexity is $O(n^2)$, where $n$ is the size of the chessboard. The space complexity is $O(1)$.
7289

7390
<!-- tabs:start -->
7491

0 commit comments

Comments
 (0)