【題目】*200. 島嶼數量
給你一個由 ‘1’(陸地)和 ‘0’(水)組成的的二維網格,請你計算網格中島嶼的數量。
島嶼總是被水包圍,並且每座島嶼只能由水平方向和/或豎直方向上相鄰的陸地連接形成。
此外,你可以假設該網格的四條邊均被水包圍。
示例 1:
輸入:
11110
11010
11000
00000
輸出: 1
示例 2:
輸入:
11000
11000
00100
00011
輸出: 3
解釋: 每座島嶼只能由水平和/或豎直方向上相鄰的陸地連接而成。
【解題思路1】DFS - flood fill
遍歷數組,遇到一個 1 就進行dfs,並將能 dfs 到的 1 都變爲 0,島嶼數 +1
class Solution {
public int numIslands(char[][] grid) {
if(grid == null || grid.length == 0){
return 0;
}
int m = grid.length;
int n = grid[0].length;
int sum = 0;
for(int i=0; i<m; i++){
for(int j=0; j<n; j++){
if(grid[i][j] == '1'){
sum++;
dfs(grid, i, j, m, n);
}
}
}
return sum;
}
public void dfs(char[][] grid, int i, int j, int m, int n){
if(i<0 || i>=m || j<0 || j>=n || grid[i][j] == '0'){
return;
}
grid[i][j] = '0'; //flood fill
dfs(grid, i-1, j, m, n);
dfs(grid, i, j-1, m, n);
dfs(grid, i+1, j, m, n);
dfs(grid, i, j+1, m, n);
}
}
【解題思路2】BFS - 隊列
class Solution {
public int numIslands(char[][] grid) {
if (grid == null || grid.length == 0) {
return 0;
}
int m = grid.length;
int n = grid[0].length;
int num_islands = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == '1') {
num_islands++;
grid[i][j] = '0';
Queue<Integer> neighbors = new LinkedList<>();
neighbors.add(i * n + j); //將元素序號存入隊列
while (!neighbors.isEmpty()) {
int id = neighbors.remove();
int row = id / n; //求出座標
int col = id % n; //可以使用方向數組優化,不必四個if
if (row - 1 >= 0 && grid[row-1][col] == '1') {
neighbors.add((row-1) * n + col);
grid[row-1][col] = '0';
}
if (row + 1 < m && grid[row+1][col] == '1') {
neighbors.add((row+1) * n + col);
grid[row+1][col] = '0';
}
if (col - 1 >= 0 && grid[row][col-1] == '1') {
neighbors.add(row * n + col-1);
grid[row][col-1] = '0';
}
if (col + 1 < n && grid[row][col+1] == '1') {
neighbors.add(row * n + col+1);
grid[row][col+1] = '0';
}
}
}
}
}
return num_islands;
}
}