1#![allow(dead_code)]
2
3pub fn num_islands(grid: Vec<Vec<char>>) -> i32 {
5 use std::iter;
6 let mut visited: Vec<Vec<bool>> = Vec::with_capacity(grid.len());
7 for _ in 0..grid.len() {
8 visited.push(iter::repeat(false).take(grid[0].len()).collect());
9 }
10 let mut count = 0;
11 for i in 0..grid.len() {
12 for j in 0..grid[0].len() {
13 if grid[i][j] == '1' && !visited[i][j] {
14 dfs(&grid, &mut visited, i, j);
15 count += 1;
16 }
17 }
18 }
19
20 count
21}
22
23fn dfs(grid: &Vec<Vec<char>>, mut visited: &mut Vec<Vec<bool>>, i: usize, j: usize) {
24 visited[i][j] = true;
25
26 if i < grid.len() - 1 && !visited[i + 1][j] && grid[i + 1][j] == '1' {
27 dfs(&grid, &mut visited, i + 1, j);
28 }
29 if i > 0 && !visited[i - 1][j] && grid[i - 1][j] == '1' {
30 dfs(&grid, &mut visited, i - 1, j);
31 }
32 if j < grid[0].len() - 1 && !visited[i][j + 1] && grid[i][j + 1] == '1' {
33 dfs(&grid, &mut visited, i, j + 1);
34 }
35 if j > 0 && !visited[i][j - 1] && grid[i][j - 1] == '1' {
36 dfs(&grid, &mut visited, i, j - 1);
37 }
38}
39
40pub fn num_islands2(grid: Vec<Vec<char>>) -> i32 {
42 use std::iter;
43 let mut visited: Vec<Vec<bool>> = Vec::with_capacity(grid.len());
44 for _ in 0..grid.len() {
45 visited.push(iter::repeat(false).take(grid[0].len()).collect());
46 }
47 let mut count = 0;
48 for i in 0..grid.len() {
49 for j in 0..grid[0].len() {
50 if grid[i][j] == '1' && !visited[i][j] {
51 bfs(&grid, &mut visited, i, j);
52 count += 1;
53 }
54 }
55 }
56
57 count
58}
59
60fn bfs(grid: &Vec<Vec<char>>, visited: &mut Vec<Vec<bool>>, i: usize, j: usize) {
61 use std::collections::LinkedList;
62 let mut q = LinkedList::new();
63 q.push_back((i, j));
64 while !q.is_empty() {
65 match q.pop_front() {
66 Some((i, j)) => {
67 visited[i][j] = true;
68 if i + 1 < grid.len() && !visited[i + 1][j] && grid[i + 1][j] == '1' {
69 q.push_back((i + 1, j));
70 }
71 if i > 0 && !visited[i - 1][j] && grid[i - 1][j] == '1' {
72 q.push_back((i - 1, j));
73 }
74 if j + 1 < grid[0].len() && !visited[i][j + 1] && grid[i][j + 1] == '1' {
75 q.push_back((i, j + 1));
76 }
77 if j > 0 && !visited[i][j - 1] && grid[i][j - 1] == '1' {
78 q.push_back((i, j - 1));
79 }
80 }
81
82 None => unreachable!(),
83 }
84 }
85}
86
87pub fn num_islands3(mut grid: Vec<Vec<char>>) -> i32 {
89 let mut count = 0;
90 for i in 0..grid.len() {
91 for j in 0..grid[0].len() {
92 if grid[i][j] == '1' {
93 bfs2(&mut grid, i, j);
94 count += 1;
95 }
96 }
97 }
98
99 count
100}
101
102fn bfs2(grid: &mut Vec<Vec<char>>, i: usize, j: usize) {
103 use std::collections::LinkedList;
104 let mut q = LinkedList::new();
105 q.push_back((i, j));
106 while !q.is_empty() {
107 match q.pop_front() {
108 Some((i, j)) => {
109 if i + 1 < grid.len() && grid[i + 1][j] == '1' {
110 grid[i + 1][j] = '0';
111 q.push_back((i + 1, j));
112 }
113 if i > 0 && grid[i - 1][j] == '1' {
114 grid[i - 1][j] = '0';
115 q.push_back((i - 1, j));
116 }
117 if j + 1 < grid[0].len() && grid[i][j + 1] == '1' {
118 grid[i][j + 1] = '0';
119 q.push_back((i, j + 1));
120 }
121 if j > 0 && grid[i][j - 1] == '1' {
122 grid[i][j - 1] = '0';
123 q.push_back((i, j - 1));
124 }
125 }
126
127 None => unreachable!(),
128 }
129 }
130}
131
132#[cfg(test)]
133mod tests {
134 use super::*;
135
136 #[test]
137 fn test1() {
138 let grid = vec![
139 vec!['1', '1', '0', '0', '0'],
140 vec!['1', '1', '0', '0', '0'],
141 vec!['0', '0', '1', '0', '0'],
142 vec!['0', '0', '0', '1', '1'],
143 ];
144
145 assert_eq!(num_islands(grid), 3);
146 }
147
148 #[test]
149 fn test2() {
150 let grid = vec![
151 vec!['1', '1', '0', '0', '0'],
152 vec!['1', '1', '0', '0', '0'],
153 vec!['0', '0', '1', '0', '0'],
154 vec!['0', '0', '0', '1', '1'],
155 ];
156
157 assert_eq!(num_islands2(grid), 3);
158 }
159
160 #[test]
161 fn test3() {
162 let grid = vec![
163 vec!['1', '1', '0', '0', '0'],
164 vec!['1', '1', '0', '0', '0'],
165 vec!['0', '0', '1', '0', '0'],
166 vec!['0', '0', '0', '1', '1'],
167 ];
168
169 assert_eq!(num_islands3(grid), 3);
170 }
171}