1. 程式人生 > 實用技巧 >LeetCode Notes_#200 島嶼數量

LeetCode Notes_#200 島嶼數量

LeetCode Notes_#200 島嶼數量

LeetCode

Contents

題目

給你一個由'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)),不知道是如何分析的...