Skip to content

Commit 1c13ed9

Browse files
committed
LC 2684. Maximum Number of Moves in a Grid (Rust)
1 parent 1bc0e33 commit 1c13ed9

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -751,6 +751,7 @@ to the solution in this repository.
751751
| [2675. Array of Objects to Matrix][lc2675] | 🟠 Medium | [![js](res/js.png)][lc2675js] |
752752
| [2676. Throttle][lc2676] | 🟠 Medium | [![js](res/js.png)][lc2676js] |
753753
| [2677. Chunk Array][lc2677] | 🟢 Easy | [![js](res/js.png)][lc2677js] |
754+
| [2684. Maximum Number of Moves in a Grid][lc2684] | 🟠 Medium | [![rust](res/rs.png)][lc2684rs] |
754755
| [2693. Call Function with Custom Context][lc2693] | 🟠 Medium | [![js](res/js.png)][lc2693js] |
755756
| [2694. Event Emitter][lc2694] | 🟠 Medium | [![js](res/js.png)][lc2694js] |
756757
| [2695. Array Wrapper][lc2695] | 🟢 Easy | [![js](res/js.png)][lc2695js] |
@@ -2429,6 +2430,8 @@ to the solution in this repository.
24292430
[lc2676js]: leetcode/throttle.js
24302431
[lc2677]: https://leetcode.com/problems/chunk-array/
24312432
[lc2677js]: leetcode/chunk-array.js
2433+
[lc2684]: https://leetcode.com/problems/maximum-number-of-moves-in-a-grid/
2434+
[lc2684rs]: leetcode/maximum-number-of-moves-in-a-grid.rs
24322435
[lc2693]: https://leetcode.com/problems/call-function-with-custom-context/
24332436
[lc2693js]: leetcode/call-function-with-custom-context.js
24342437
[lc2694]: https://leetcode.com/problems/event-emitter/
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// 2684. Maximum Number of Moves in a Grid
2+
// 🟠 Medium
3+
//
4+
// https://leetcode.com/problems/maximum-number-of-moves-in-a-grid/
5+
//
6+
// Tags: Array - Dynamic Programming - Matrix
7+
8+
use std::mem::swap;
9+
10+
struct Solution;
11+
impl Solution {
12+
/// Use dynamic programming, use a dp vector to determine which cells in the previous column
13+
/// are reachable, initialize it at all true. The transition is marking the cell as reachable
14+
/// if we can reach it from any of its three neighbors in the previous rows. For that to be
15+
/// true, at least one of its neighbors on the top-left, left or bottom-left needs to be
16+
/// reachable and have a value that is strictly lower.
17+
///
18+
/// Time complexity: O(m*n) - We may visit each cell in the grid and do three conditional
19+
/// checks for each using constant time.
20+
/// Space complexity: O(m) - We use two vectors of the length of a column to store intermediate
21+
/// results.
22+
///
23+
/// Runtime 0 ms Beats 100%
24+
/// Memory 3.84 MB Beats 100%
25+
pub fn max_moves(grid: Vec<Vec<i32>>) -> i32 {
26+
let (num_rows, num_cols) = (grid.len(), grid[0].len());
27+
let (mut prev, mut dp) = (vec![true; num_rows], vec![false; num_rows]);
28+
let mut can_move;
29+
for col in 1..num_cols {
30+
can_move = false;
31+
for row in 0..num_rows {
32+
dp[row] = (prev[row] && grid[row][col - 1] < grid[row][col])
33+
|| (row > 0 && prev[row - 1] && grid[row - 1][col - 1] < grid[row][col])
34+
|| (row < num_rows - 1
35+
&& prev[row + 1]
36+
&& grid[row + 1][col - 1] < grid[row][col]);
37+
if dp[row] {
38+
can_move = true;
39+
}
40+
}
41+
if !can_move {
42+
return col as i32 - 1;
43+
}
44+
swap(&mut dp, &mut prev);
45+
}
46+
num_cols as i32 - 1
47+
}
48+
}
49+
50+
// Tests.
51+
fn main() {
52+
let tests = [
53+
(
54+
vec![
55+
vec![2, 4, 3, 5],
56+
vec![5, 4, 9, 3],
57+
vec![3, 4, 2, 11],
58+
vec![10, 9, 13, 15],
59+
],
60+
3,
61+
),
62+
(vec![vec![3, 2, 4], vec![2, 1, 9], vec![1, 1, 7]], 0),
63+
(
64+
vec![
65+
vec![187, 167, 209, 251, 152, 236, 263, 128, 135],
66+
vec![267, 249, 251, 285, 73, 204, 70, 207, 74],
67+
vec![189, 159, 235, 66, 84, 89, 153, 111, 189],
68+
vec![120, 81, 210, 7, 2, 231, 92, 128, 218],
69+
vec![193, 131, 244, 293, 284, 175, 226, 205, 245],
70+
],
71+
3,
72+
),
73+
];
74+
println!("\n\x1b[92m» Running {} tests...\x1b[0m", tests.len());
75+
let mut success = 0;
76+
for (i, t) in tests.iter().enumerate() {
77+
let res = Solution::max_moves(t.0.clone());
78+
if res == t.1 {
79+
success += 1;
80+
println!("\x1b[92m✔\x1b[95m Test {} passed!\x1b[0m", i);
81+
} else {
82+
println!(
83+
"\x1b[31mx\x1b[95m Test {} failed expected: {:?} but got {}!!\x1b[0m",
84+
i, t.1, res
85+
);
86+
}
87+
}
88+
println!();
89+
if success == tests.len() {
90+
println!("\x1b[30;42m✔ All tests passed!\x1b[0m")
91+
} else if success == 0 {
92+
println!("\x1b[31mx \x1b[41;37mAll tests failed!\x1b[0m")
93+
} else {
94+
println!(
95+
"\x1b[31mx\x1b[95m {} tests failed!\x1b[0m",
96+
tests.len() - success
97+
)
98+
}
99+
}

0 commit comments

Comments
 (0)