Skip to content

Commit 7526755

Browse files
committed
一刷2684
1 parent 73ec62a commit 7526755

8 files changed

+178
-39
lines changed

README.adoc

+6-6
Original file line numberDiff line numberDiff line change
@@ -18814,12 +18814,12 @@ TIP: **公众号的微信号是: `jikerizhi`**。__因为众所周知的原因
1881418814
//|Medium
1881518815
//|
1881618816

18817-
//|{counter:codes}
18818-
//|{leetcode_base_url}/maximum-number-of-moves-in-a-grid/[2684. Maximum Number of Moves in a Grid^]
18819-
//|{source_base_url}/_2684_MaximumNumberOfMovesInAGrid.java[Java]
18820-
//|{doc_base_url}/2684-maximum-number-of-moves-in-a-grid.adoc[题解]
18821-
//|Medium
18822-
//|
18817+
|{counter:codes}
18818+
|{leetcode_base_url}/maximum-number-of-moves-in-a-grid/[2684. Maximum Number of Moves in a Grid^]
18819+
|{source_base_url}/_2684_MaximumNumberOfMovesInAGrid.java[Java]
18820+
|{doc_base_url}/2684-maximum-number-of-moves-in-a-grid.adoc[题解]
18821+
|Medium
18822+
|
1882318823

1882418824
//|{counter:codes}
1882518825
//|{leetcode_base_url}/count-the-number-of-complete-components/[2685. Count the Number of Complete Components^]
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,61 @@
11
[#2684-maximum-number-of-moves-in-a-grid]
2-
= 2684. Maximum Number of Moves in a Grid
2+
= 2684. 矩阵中移动的最大次数
33

4-
{leetcode}/problems/maximum-number-of-moves-in-a-grid/[LeetCode - 2684. Maximum Number of Moves in a Grid ^]
4+
https://leetcode.cn/problems/maximum-number-of-moves-in-a-grid/[LeetCode - 2684. 矩阵中移动的最大次数 ^]
55

6-
You are given a *0-indexed* `m x n` matrix `grid` consisting of *positive* integers.
6+
给你一个下标从 *0* 开始、大小为 `m x n` 的矩阵 `grid` ,矩阵由若干 *正* 整数组成。
77

8-
You can start at *any* cell in the first column of the matrix, and traverse the grid in the following way:
8+
你可以从矩阵第一列中的 *任一* 单元格出发,按以下方式遍历 `grid`
99

10+
* 从单元格 `(row, col)` 可以移动到 `(row - 1, col + 1)``(row, col + 1)``(row + 1, col + 1)` 三个单元格中任一满足值 *严格* 大于当前单元格的单元格。
1011
11-
* From a cell `(row, col)`, you can move to any of the cells: `(row - 1, col + 1)`, `(row, col + 1)` and `(row + 1, col + 1)` such that the value of the cell you move to, should be *strictly* bigger than the value of the current cell.
12+
返回你在矩阵中能够 *移动**最大* 次数。
1213

14+
*示例 1:*
1315

14-
Return _the *maximum* number of *moves* that you can perform._
16+
image::images/2684-01.png[{image_attr}]
1517

16-
17-
*Example 1:*
18-
<img alt="" src="https://assets.leetcode.com/uploads/2023/04/11/yetgriddrawio-10.png" style="width: 201px; height: 201px;" />
19-
[subs="verbatim,quotes"]
20-
----
21-
*Input:* grid = [[2,4,3,5],[5,4,9,3],[3,4,2,11],[10,9,13,15]]
22-
*Output:* 3
23-
*Explanation:* We can start at the cell (0, 0) and make the following moves:
18+
....
19+
输入:grid = [[2,4,3,5],[5,4,9,3],[3,4,2,11],[10,9,13,15]]
20+
输出:3
21+
解释:可以从单元格 (0, 0) 开始并且按下面的路径移动:
2422
- (0, 0) -> (0, 1).
2523
- (0, 1) -> (1, 2).
2624
- (1, 2) -> (2, 3).
27-
It can be shown that it is the maximum number of moves that can be made.
28-
----
25+
可以证明这是能够移动的最大次数。
26+
....
2927

30-
*Example 2:*
28+
*示例 2:*
3129

32-
[subs="verbatim,quotes"]
33-
----
34-
<img alt="" src="https://assets.leetcode.com/uploads/2023/04/12/yetgrid4drawio.png" />
35-
*Input:* grid = [[3,2,4],[2,1,9],[1,1,7]]
36-
*Output:* 0
37-
*Explanation:* Starting from any cell in the first column we cannot perform any moves.
38-
39-
----
30+
image::images/2684-02.png[{image_attr}]
4031

41-
42-
*Constraints:*
32+
....
33+
输入:grid = [[3,2,4],[2,1,9],[1,1,7]]
34+
输出:0
35+
解释:从第一列的任一单元格开始都无法移动。
36+
....
4337

38+
*提示:*
4439

4540
* `m == grid.length`
4641
* `n == grid[i].length`
47-
* `2 <= m, n <= 1000`
48-
* `4 <= m * n <= 10^5^`
49-
* `1 <= grid[i][j] <= 10^6^`
42+
* `+2 <= m, n <= 1000+`
43+
* `4 \<= m * n \<= 10^5^`
44+
* `1 \<= grid[i][j] \<= 10^6^`
5045
5146
47+
== 思路分析
5248

49+
首先想到的思路是回溯,从第一列每个位置出发,向右进行探索,成功前进,失败则回溯。思路正确,通过 810 / 814 个测试用例。然后,超时。
5350

54-
== 思路分析
51+
TIP: 又想了想,这不能叫回溯,因为没有回溯动作。应该是深度优先搜索。
5552

53+
后想到动态规划。初始化一个同样大小的二维数组,每个表格记录到达该点需要行走记录。从左向右,按列遍历即可。
5654

5755
[[src-2684]]
5856
[tabs]
5957
====
60-
一刷::
58+
一刷(深度优先搜索)::
6159
+
6260
--
6361
[{java_src_attr}]
@@ -66,6 +64,15 @@ include::{sourcedir}/_2684_MaximumNumberOfMovesInAGrid.java[tag=answer]
6664
----
6765
--
6866
67+
一刷(动态规划)::
68+
+
69+
--
70+
[{java_src_attr}]
71+
----
72+
include::{sourcedir}/_2684_MaximumNumberOfMovesInAGrid_1.java[tag=answer]
73+
----
74+
--
75+
6976
// 二刷::
7077
// +
7178
// --
@@ -79,4 +86,9 @@ include::{sourcedir}/_2684_MaximumNumberOfMovesInAGrid.java[tag=answer]
7986

8087
== 参考资料
8188

89+
. https://leetcode.cn/problems/maximum-number-of-moves-in-a-grid/solutions/2684036/ju-zhen-zhong-yi-dong-de-zui-da-ci-shu-b-b7jx/[2684. 矩阵中移动的最大次数 - 官方题解^] -- 广度优先搜索的解法。其实,每次遍历只需要保存当前列可以到达的节点坐标即可,当没有坐标可以到达时,已经走到了尽头。这个解法更简单高效。
90+
. https://leetcode.cn/problems/maximum-number-of-moves-in-a-grid/solutions/2269244/cong-ji-yi-hua-sou-suo-dao-di-tui-by-end-pgq3/[2684. 矩阵中移动的最大次数 - 两种方法:DFS / BFS^] -- 深度优先遍历的解法非常有意思,把到达的处理后的节点都设置成 `0`,这样就可以有效避免重复遍历,加快处理速度。
91+
92+
93+
8294

docs/images/2684-01.png

16.8 KB
Loading

docs/images/2684-02.png

8.21 KB
Loading

docs/index.adoc

+1-1
Original file line numberDiff line numberDiff line change
@@ -5452,7 +5452,7 @@ include::2560-house-robber-iv.adoc[leveloffset=+1]
54525452

54535453
// include::2683-neighboring-bitwise-xor.adoc[leveloffset=+1]
54545454

5455-
// include::2684-maximum-number-of-moves-in-a-grid.adoc[leveloffset=+1]
5455+
include::2684-maximum-number-of-moves-in-a-grid.adoc[leveloffset=+1]
54565456

54575457
// include::2685-count-the-number-of-complete-components.adoc[leveloffset=+1]
54585458

logbook/202503.adoc

+5
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,11 @@ endif::[]
608608
|{doc_base_url}/0199-binary-tree-right-side-view.adoc[题解]
609609
|✅ 深度优先遍历。按照 `<level, node>` 的格式,把每个节点都放到 `Map` 里,因为是先左后右,所以,每层最后只剩下了最右边的元素。
610610

611+
|{counter:codes2503}
612+
|{leetcode_base_url}/maximum-number-of-moves-in-a-grid/[2684. Maximum Number of Moves in a Grid^]
613+
|{doc_base_url}/2684-maximum-number-of-moves-in-a-grid.adoc[题解]
614+
|✅ 动态规划。也可以使用深度优先搜索的解法,使用深度优先搜索时,需要把处理过的节点值设置为 `0`,防止重新判断,加快处理速度。
615+
611616
|===
612617

613618
截止目前,本轮练习一共完成 {codes2503} 道题。
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.diguage.algo.leetcode;
2+
3+
public class _2684_MaximumNumberOfMovesInAGrid {
4+
// tag::answer[]
5+
6+
/**
7+
* 通过 810 / 814 个测试用例。超时
8+
*
9+
* @author D瓜哥 · https://www.diguage.com
10+
* @since 2025-05-05 22:11:52
11+
*/
12+
public int maxMoves(int[][] grid) {
13+
int result = 0;
14+
for (int i = 0; i < grid.length; i++) {
15+
result = Math.max(result, dfs(grid, i, 0));
16+
if (result == grid[i].length) {
17+
break;
18+
}
19+
}
20+
return result;
21+
}
22+
23+
private int dfs(int[][] grid, int row, int column) {
24+
if (column == grid[row].length - 1) {
25+
return 0;
26+
}
27+
int result = -1;
28+
if (row - 1 >= 0 && column + 1 < grid[row - 1].length
29+
&& grid[row][column] < grid[row - 1][column + 1]) {
30+
result = Math.max(result, dfs(grid, row - 1, column + 1));
31+
}
32+
if (column + 1 < grid[row].length
33+
&& grid[row][column] < grid[row][column + 1]) {
34+
result = Math.max(result, dfs(grid, row, column + 1));
35+
}
36+
if (row + 1 < grid.length && column + 1 < grid[row + 1].length
37+
&& grid[row][column] < grid[row + 1][column + 1]) {
38+
result = Math.max(result, dfs(grid, row + 1, column + 1));
39+
}
40+
// 受灵茶山艾府题解启发,加这么一行代码,答案即可通过。
41+
grid[row][column] = 0;
42+
return result + 1;
43+
}
44+
45+
// end::answer[]
46+
public static void main(String[] args) {
47+
new _2684_MaximumNumberOfMovesInAGrid().maxMoves(new int[][]{
48+
{65, 200, 263, 220, 91, 183, 2, 187, 175, 61, 225, 120, 39},
49+
{111, 242, 294, 31, 241, 90, 145, 25, 262, 214, 145, 71, 294},
50+
{152, 25, 240, 69, 279, 238, 222, 9, 137, 277, 8, 143, 143},
51+
{189, 31, 86, 250, 20, 63, 188, 209, 75, 22, 127, 272, 110},
52+
{122, 94, 298, 25, 90, 169, 68, 3, 208, 274, 202, 135, 275},
53+
{205, 20, 171, 90, 70, 272, 280, 138, 142, 151, 80, 122, 130},
54+
{284, 272, 271, 269, 265, 134, 185, 243, 247, 50, 283, 20, 232},
55+
{266, 236, 265, 234, 249, 62, 98, 130, 122, 226, 285, 168, 204},
56+
{231, 24, 256, 101, 142, 28, 268, 82, 111, 63, 115, 13, 144},
57+
{277, 277, 31, 144, 49, 132, 28, 138, 133, 29, 286, 45, 93},
58+
{163, 96, 25, 9, 3, 159, 148, 59, 25, 81, 233, 127, 12},
59+
{127, 38, 31, 209, 300, 256, 15, 43, 74, 64, 73, 141, 200}
60+
});
61+
}
62+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package com.diguage.algo.leetcode;
2+
3+
public class _2684_MaximumNumberOfMovesInAGrid_1 {
4+
// tag::answer[]
5+
6+
/**
7+
* @author D瓜哥 · https://www.diguage.com
8+
* @since 2025-05-05 22:38:45
9+
*/
10+
public int maxMoves(int[][] grid) {
11+
int m = grid.length, n = grid[0].length;
12+
int[][] dp = new int[m][n];
13+
int result = 0;
14+
// 📢:注意这里的遍历顺序,需要按列向右推进
15+
for (int column = 1; column < n; column++) {
16+
// 不加 stop,击败 12.96%;加 stop,击败 50.07%
17+
boolean stop = true;
18+
for (int row = 0; row < m; row++) {
19+
if (row - 1 >= 0 && grid[row - 1][column - 1] < grid[row][column]
20+
&& (column == 1 || dp[row - 1][column - 1] > 0)) {
21+
dp[row][column] = Math.max(dp[row][column], dp[row - 1][column - 1] + 1);
22+
stop = false;
23+
}
24+
if (grid[row][column - 1] < grid[row][column]
25+
&& (column == 1 || dp[row][column - 1] > 0)) {
26+
dp[row][column] = Math.max(dp[row][column], dp[row][column - 1] + 1);
27+
stop = false;
28+
}
29+
if (row + 1 < m && grid[row + 1][column - 1] < grid[row][column]
30+
&& (column == 1 || dp[row + 1][column - 1] > 0)) {
31+
dp[row][column] = Math.max(dp[row][column], dp[row + 1][column - 1] + 1);
32+
stop = false;
33+
}
34+
result = Math.max(result, dp[row][column]);
35+
}
36+
if (stop) {
37+
return result;
38+
}
39+
}
40+
return result;
41+
}
42+
43+
// end::answer[]
44+
public static void main(String[] args) {
45+
new _2684_MaximumNumberOfMovesInAGrid_1().maxMoves(new int[][]{
46+
{65, 200, 263, 220, 91, 183, 2, 187, 175, 61, 225, 120, 39},
47+
{111, 242, 294, 31, 241, 90, 145, 25, 262, 214, 145, 71, 294},
48+
{152, 25, 240, 69, 279, 238, 222, 9, 137, 277, 8, 143, 143},
49+
{189, 31, 86, 250, 20, 63, 188, 209, 75, 22, 127, 272, 110},
50+
{122, 94, 298, 25, 90, 169, 68, 3, 208, 274, 202, 135, 275},
51+
{205, 20, 171, 90, 70, 272, 280, 138, 142, 151, 80, 122, 130},
52+
{284, 272, 271, 269, 265, 134, 185, 243, 247, 50, 283, 20, 232},
53+
{266, 236, 265, 234, 249, 62, 98, 130, 122, 226, 285, 168, 204},
54+
{231, 24, 256, 101, 142, 28, 268, 82, 111, 63, 115, 13, 144},
55+
{277, 277, 31, 144, 49, 132, 28, 138, 133, 29, 286, 45, 93},
56+
{163, 96, 25, 9, 3, 159, 148, 59, 25, 81, 233, 127, 12},
57+
{127, 38, 31, 209, 300, 256, 15, 43, 74, 64, 73, 141, 200}
58+
});
59+
}
60+
}

0 commit comments

Comments
 (0)