LeetCode Notes_#200 島嶼數量
阿新 • • 發佈:2020-09-03
LeetCode Notes_#200 島嶼數量
LeetCodeContents
題目
給你一個由'0'(水)和'1'(陸地)組成的的二維網格,請你計算網格中島嶼的數量。
島嶼總是被水包圍,並且每座島嶼只能由水平方向或豎直方向上相鄰的陸地連線形成。
此外,你可以假設該網格的四條邊均被水包圍。
示例1:
輸入:
[
['1','1','1','1','0'],
['1','1','0','1','0'],
['1','1','0','0','0'],
['0','0','0','0','0']
]
輸出:1
示例2:
輸入: [ ['1','1','0','0','0'], ['1','1','0','0','0'], ['0','0','1','0','0'], ['0','0','0','1','1'] ] 輸出: 3 解釋: 每座島嶼只能由水平和/或豎直方向上相鄰的陸地連線而成。
思路分析
一個島嶼是由一些在上下左右方向上相鄰的'1'所構成的。我們在計數的時候,只需要計數每一個島嶼裡第一次訪問的'1'就行了。然後就往上下左右四個方向進行搜尋,直到遇到grid
的邊界,或者遇到水面'0'。
搜尋有兩種方法,DFS和BFS。
需要特別注意的一點是,在輔助函式dfs
/bfs
當中,需要把訪問到的'1'元素置為'0',防止在主迴圈當中訪問第二次。
解答
方法1:DFS
class Solution {
public int numIslands(char[][] grid) {
int count = 0;
//主迴圈
for (int i = 0;i <= grid.length - 1;i++){
for(int j = 0;j <= grid[0].length - 1;j++){
//遇到一個位置是陸地('1'),那麼使用dfs搜尋它的邊界
if(grid[i][j] == '1'){
dfs(grid, i, j);
//然後計數器增加1
count++;
}
}
}
return count;
}
private void dfs(char[][] grid, int i, int j){
//遇到水面('0')或者是網格的邊界,就停止搜尋
if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == '0') return;
//一個島嶼當中只有在主迴圈裡第一次訪問的'1'需要計數,所以將訪問完的元素置為'0',避免重複計數
grid[i][j] = '0';
dfs(grid, i + 1, j);
dfs(grid, i , j + 1);
dfs(grid, i - 1, j);
dfs(grid, i, j - 1);
}
}
複雜度分析
時間複雜度:O(MN)
,M,N是gird
網格的行數和列數。
空間複雜度:O(MN)
,如果整個矩陣都是陸地'1',那麼遞迴呼叫了MN次,佔用的系統棧深度是O(MN)
。
方法2:BFS
class Solution {
public int numIslands(char[][] grid) {
int count = 0;
//主迴圈
for(int i = 0;i <= grid.length - 1;i++){
for(int j = 0;j <= grid[0].length - 1;j++){
//遇到一個位置是陸地('1'),那麼使用bfs搜尋它的邊界
if(grid[i][j] == '1'){
bfs(grid, i, j);
//然後計數器增加1
count++;
}
}
}
return count;
}
private void bfs(char[][] grid, int i, int j){
Queue<int[]> queue = new LinkedList<>();
//放入一個島嶼中首次被訪問的'1'的座標
queue.offer(new int[]{i,j});
while(!queue.isEmpty()){
int[] cur = queue.poll();
i = cur[0];
j = cur[1];
if(i >= 0 && i <= grid.length - 1 && j >= 0 && j <= grid[0].length - 1 && grid[i][j] == '1'){
grid[i][j] = '0';
queue.offer(new int[]{i + 1,j});
queue.offer(new int[]{i,j + 1});
queue.offer(new int[]{i - 1,j});
queue.offer(new int[]{i,j - 1});
}
}
}
}
複雜度分析
時間複雜度:O(MN)
空間複雜度:O(min(M,N))
,不知道是如何分析的...