LeetCode/rs/shortest-path-in-binary-matrix.rs

107 lines
2.8 KiB
Rust
Raw Permalink Normal View History

use std::collections::VecDeque;
use std::convert::TryInto;
struct Solution {}
impl Solution {
pub fn shortest_path_binary_matrix(grid: Vec<Vec<i32>>) -> i32 {
let n = grid.len();
// create an array of distances
let mut distances = grid.clone();
for y in 0..n {
for x in 0..n {
distances[y][x] = -1;
}
}
// initialize the start with an initial distance
let mut q: VecDeque<(usize, usize)> = VecDeque::new();
if grid[0][0] == 0 {
distances[0][0] = 1;
q.push_back((0, 0));
}
while let Some((y, x)) = q.pop_front() {
if (y, x) == (n - 1, n - 1) {
break;
}
for (next_y, next_x) in (-1_isize..=1)
.flat_map(|dy| (-1_isize..=1).map(move |dx| (dy, dx)))
.map(|(dy, dx)| (y as isize + dy, x as isize + dx))
.filter(|&(next_y, next_x)| {
(next_y, next_x) != (y as isize, x as isize)
&& next_y >= 0
&& next_y < n.try_into().unwrap()
&& next_x >= 0
&& next_x < n.try_into().unwrap()
})
{
let (next_y, next_x) = (next_y as usize, next_x as usize);
if distances[next_y][next_x] == -1 && grid[next_y][next_x] == 0 {
distances[next_y][next_x] = distances[y][x] + 1;
q.push_back((
(next_y as isize).try_into().unwrap(),
(next_x as isize).try_into().unwrap(),
));
}
}
}
distances[n - 1][n - 1]
}
}
fn main() {
assert_eq!(
Solution::shortest_path_binary_matrix(vec![vec![0, 1], vec![1, 0]]),
2
);
assert_eq!(
Solution::shortest_path_binary_matrix(vec![vec![0, 0, 0], vec![1, 1, 0], vec![1, 1, 0]]),
4
);
assert_eq!(
Solution::shortest_path_binary_matrix(vec![vec![1, 0, 0], vec![1, 1, 0], vec![1, 1, 0]]),
-1
);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn example_1() {
assert_eq!(
Solution::shortest_path_binary_matrix(vec![vec![0, 1], vec![1, 0]]),
2
);
}
#[test]
fn example_2() {
assert_eq!(
Solution::shortest_path_binary_matrix(vec![
vec![0, 0, 0],
vec![1, 1, 0],
vec![1, 1, 0]
]),
4
);
}
#[test]
fn example_3() {
assert_eq!(
Solution::shortest_path_binary_matrix(vec![
vec![1, 0, 0],
vec![1, 1, 0],
vec![1, 1, 0]
]),
-1
);
}
}