rs: add «200. Number of Islands»

Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
Matej Focko 2024-04-19 19:48:00 +02:00
parent 3984bbb534
commit 1e0acf7f10
Signed by: mfocko
GPG key ID: 7C47D46246790496

View file

@ -0,0 +1,61 @@
use std::collections::VecDeque;
impl Solution {
fn dimensions(grid: &[Vec<char>]) -> (usize, usize) {
(grid.len(), grid[0].len())
}
fn in_range(grid: &[Vec<char>], x: isize, y: isize) -> bool {
y >= 0 && y < grid.len() as isize && x >= 0 && x < grid[y as usize].len() as isize
}
fn get_neighbors(
grid: &[Vec<char>],
visited: &[Vec<bool>],
x: isize,
y: isize,
) -> Vec<(isize, isize)> {
[-1, 1]
.into_iter()
.flat_map(|d| [(x + d, y), (x, y + d)])
.filter(|&(x, y)| {
Self::in_range(grid, x, y)
&& !visited[y as usize][x as usize]
&& grid[y as usize][x as usize] == '1'
})
.collect()
}
fn bfs(grid: &[Vec<char>], visited: &mut [Vec<bool>], x: isize, y: isize) {
let mut q: VecDeque<(isize, isize)> = VecDeque::from([(x, y)]);
visited[y as usize][x as usize] = true;
while let Some((x, y)) = q.pop_back() {
Self::get_neighbors(grid, visited, x, y)
.into_iter()
.for_each(|(x, y)| {
q.push_back((x, y));
visited[y as usize][x as usize] = true;
});
}
}
pub fn num_islands(grid: Vec<Vec<char>>) -> i32 {
let (m, n) = Self::dimensions(&grid);
let mut visited = vec![vec![false; n]; m];
let mut islands = 0;
for idx in 0..m * n {
let (y, x) = (idx / n, idx % n);
if visited[y][x] || grid[y][x] == '0' {
continue;
}
islands += 1;
Self::bfs(&grid, &mut visited, x as isize, y as isize);
}
islands
}
}