mirror of
https://gitlab.com/mfocko/LeetCode.git
synced 2024-11-10 00:09:06 +01:00
61 lines
1.7 KiB
Rust
61 lines
1.7 KiB
Rust
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
|
|
}
|
|
}
|