diff --git a/rs/2024-04-19-number-of-islands.rs b/rs/2024-04-19-number-of-islands.rs new file mode 100644 index 0000000..c7b2b3b --- /dev/null +++ b/rs/2024-04-19-number-of-islands.rs @@ -0,0 +1,61 @@ +use std::collections::VecDeque; + +impl Solution { + fn dimensions(grid: &[Vec]) -> (usize, usize) { + (grid.len(), grid[0].len()) + } + + fn in_range(grid: &[Vec], 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], + visited: &[Vec], + 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], visited: &mut [Vec], 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>) -> 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 + } +}