LeetCode/rs/number-of-islands.rs

93 lines
2.4 KiB
Rust
Raw Permalink Normal View History

use std::collections::{HashSet, VecDeque};
type Position = (i32, i32);
type Grid = Vec<Vec<char>>;
impl Solution {
fn indices(grid: &Grid) -> impl Iterator<Item = Position> + '_ {
(0..grid.len() as i32)
.flat_map(move |y| (0..grid[y as usize].len() as i32).map(move |x| (y, x)))
}
fn interesting(grid: &Grid, visited: &HashSet<Position>, p: &Position) -> bool {
let (max_y, max_x) = (grid.len() as i32, grid[0].len() as i32);
let &(y, x) = p;
y >= 0
&& y < max_y
&& x >= 0
&& x < max_x
&& grid[p.0 as usize][p.1 as usize] != '0'
&& !visited.contains(p)
}
fn bfs(grid: &Grid, visited: &mut HashSet<Position>, pos: Position) {
let mut queue: VecDeque<Position> = VecDeque::new();
queue.push_back(pos);
visited.insert(pos);
while let Some(p) = queue.pop_front() {
for d in [-1, 1] {
for adjacent in [(p.0 + d, p.1), (p.0, p.1 + d)] {
if Solution::interesting(grid, visited, &adjacent) {
queue.push_back(adjacent);
visited.insert(adjacent);
}
}
}
}
}
pub fn num_islands(grid: Grid) -> i32 {
let mut visited: HashSet<Position> = HashSet::new();
let mut islands = 0;
for (y, x) in Solution::indices(&grid) {
if !Solution::interesting(&grid, &visited, &(y, x)) {
continue;
}
Solution::bfs(&grid, &mut visited, (y, x));
islands += 1;
}
islands
}
}
struct Solution {}
fn main() {
println!("Hello World!");
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_example_1() {
assert_eq!(
Solution::num_islands(vec![
vec!['1', '1', '1', '1', '0'],
vec!['1', '1', '0', '1', '0'],
vec!['1', '1', '0', '0', '0'],
vec!['0', '0', '0', '0', '0']
]),
1
);
}
#[test]
fn test_example_2() {
assert_eq!(
Solution::num_islands(vec![
vec!['1', '1', '0', '0', '0'],
vec!['1', '1', '0', '0', '0'],
vec!['0', '0', '1', '0', '0'],
vec!['0', '0', '0', '1', '1']
]),
3
);
}
}