Skip to content

Commit

Permalink
add: 最小体力消耗路径
Browse files Browse the repository at this point in the history
  • Loading branch information
yi-ge committed Dec 11, 2023
1 parent 8c26a3d commit c012af6
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 0 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,10 @@ Rust标准库`std::collections`提供了4种通用容器类型,包含一下8

### 其它

- [最小体力消耗路径](src/search/path_with_minimum_effort.rs) [深度优先搜索, 广度优先搜索, 并查集, 数组, 二分查找, 矩阵, 堆(优先队列)]

- LeetCode 1631. 最小体力消耗路径 <https://leetcode.cn/problems/path-with-minimum-effort>

- [爬楼梯](src/search/climbing_stairs.rs) [记忆化搜索, 数学, 动态规划]

- LeetCode 70. 爬楼梯 <https://leetcode.cn/problems/climbing-stairs>
Expand Down
Binary file added images/search/path_with_minimum_effort.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/search/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ pub mod number_of_closed_islands;
pub mod pond_sizes_lcci;
pub mod shortest_path_in_binary_matrix;
pub mod climbing_stairs;
pub mod path_with_minimum_effort;
47 changes: 47 additions & 0 deletions src/search/path_with_minimum_effort.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// 最小体力消耗路径
// https://leetcode.cn/problems/path-with-minimum-effort
// INLINE ../../images/search/path_with_minimum_effort.jpeg
use std::cmp::{max, Reverse};
use std::collections::BinaryHeap;

pub struct Solution;

impl Solution {
pub fn minimum_effort_path(heights: Vec<Vec<i32>>) -> i32 {
let m = heights.len();
let n = heights[0].len();

let mut heap = BinaryHeap::new();
heap.push((Reverse(0), 0, 0));

let mut dist = vec![std::i32::MAX; m * n];
dist[0] = 0;
let mut seen = vec![false; m * n];

while let Some((Reverse(d), x, y)) = heap.pop() {
let id = x * n + y;
if seen[id] {
continue;
}
if x == m - 1 && y == n - 1 {
break;
}
seen[id] = true;
for dir in &[[0, 1], [0, -1], [1, 0], [-1, 0]] {
let nx = x as i32 + dir[0];
let ny = y as i32 + dir[1];
if nx >= 0 && nx < m as i32 && ny >= 0 && ny < n as i32 {
let nx = nx as usize;
let ny = ny as usize;
let effort = max(d, (heights[x][y] - heights[nx][ny]).abs());
if effort < dist[nx * n + ny] {
dist[nx * n + ny] = effort;
heap.push((Reverse(effort), nx, ny));
}
}
}
}

dist[m * n - 1]
}
}
1 change: 1 addition & 0 deletions tests/search/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ pub mod number_of_closed_islands_test;
pub mod pond_sizes_lcci_test;
pub mod shortest_path_in_binary_matrix_test;
pub mod climbing_stairs_test;
pub mod path_with_minimum_effort_test;
32 changes: 32 additions & 0 deletions tests/search/path_with_minimum_effort_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use rust_practice::search::path_with_minimum_effort::Solution;

#[test]
fn minimum_effort_path() {
// 示例 1:
// 输入:heights = [[1,2,2],[3,8,2],[5,3,5]]
// 输出:2
// 解释:路径 [1,3,5,3,5] 连续格子的差值绝对值最大为 2 。
// 这条路径比路径 [1,2,2,2,5] 更优,因为另一条路径差值最大值为 3 。
let heights = vec![vec![1, 2, 2], vec![3, 8, 2], vec![5, 3, 5]];
assert_eq!(Solution::minimum_effort_path(heights), 2);

// 示例 2:
// 输入:heights = [[1,2,3],[3,8,4],[5,3,5]]
// 输出:1
// 解释:路径 [1,2,3,4,5] 的相邻格子差值绝对值最大为 1 ,比路径 [1,3,5,3,5] 更优。
let heights = vec![vec![1, 2, 3], vec![3, 8, 4], vec![5, 3, 5]];
assert_eq!(Solution::minimum_effort_path(heights), 1);

// 示例 3:
// 输入:heights = [[1,2,1,1,1],[1,2,1,2,1],[1,2,1,2,1],[1,2,1,2,1],[1,1,1,2,1]]
// 输出:0
// 解释:上图所示路径不需要消耗任何体力。
let heights = vec![
vec![1, 2, 1, 1, 1],
vec![1, 2, 1, 2, 1],
vec![1, 2, 1, 2, 1],
vec![1, 2, 1, 2, 1],
vec![1, 1, 1, 2, 1],
];
assert_eq!(Solution::minimum_effort_path(heights), 0);
}

0 comments on commit c012af6

Please sign in to comment.