-
Notifications
You must be signed in to change notification settings - Fork 0
/
number_of_islands.rs
110 lines (97 loc) · 3.22 KB
/
number_of_islands.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use std::collections::HashSet;
/// Given an `m x n` 2D binary `grid` which represents a map of `'1'`s (land)
/// and `'0'`s (water), return the number of islands.
///
/// An island is surrounded by water and is formed by connecting adjacent lands
/// horizontally or vertically. You may assume all four edges of the grid are
/// surrounded by water.
struct Solution;
impl Solution {
fn row_len(grid: &Vec<Vec<char>>) -> usize {
grid.len()
}
fn col_len(grid: &Vec<Vec<char>>) -> usize {
if Self::row_len(grid) > 0 {
grid[0].len()
} else {
0
}
}
pub fn num_islands(grid: Vec<Vec<char>>) -> i32 {
let mut result = 0;
let mut seen = HashSet::new();
for row in 0..Self::row_len(&grid) {
for col in 0..Self::col_len(&grid) {
let key = (row, col);
if Self::is_land(&grid, row, col) && !seen.contains(&key) {
result += 1;
seen.insert(key);
Self::worker(&grid, &mut seen, row, col);
}
}
}
result
}
fn is_land(grid: &Vec<Vec<char>>, row: usize, col: usize) -> bool {
grid[row][col] == '1'
}
fn worker(grid: &Vec<Vec<char>>, seen: &mut HashSet<(usize, usize)>, row: usize, col: usize) {
let directions = vec!['N', 'S', 'E', 'W'];
for dir in &directions {
let mut neighbor_row: i32 = row as i32;
let mut neighbor_col: i32 = col as i32;
match dir {
'N' => {
neighbor_row -= 1;
}
'S' => {
neighbor_row += 1;
}
'E' => {
neighbor_col += 1;
}
'W' => {
neighbor_col -= 1;
}
_ => {}
}
let valid_row = neighbor_row >= 0 && neighbor_row < Self::row_len(&grid) as i32;
let valid_col = neighbor_col >= 0 && neighbor_col < Self::col_len(&grid) as i32;
if valid_row && valid_col {
let neighbor_row = neighbor_row as usize;
let neighbor_col = neighbor_col as usize;
let key = (neighbor_row, neighbor_col);
if Self::is_land(grid, neighbor_row, neighbor_col) && !seen.contains(&key) {
seen.insert(key);
Self::worker(grid, seen, neighbor_row, neighbor_col);
}
}
}
}
}
#[cfg(test)]
mod tests {
use super::Solution;
#[test]
fn example_1() {
let grid = 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'],
];
let result = Solution::num_islands(grid);
assert_eq!(result, 1);
}
#[test]
fn example_2() {
let grid = 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'],
];
let result = Solution::num_islands(grid);
assert_eq!(result, 3);
}
}