Leetcode 200 Number of Islands 笔记

157 阅读1分钟

Medium

思想

  • 遍历所有点,判断点是否为陆地
  • 如果是陆地, recursion去判断周围, 上下左右是否为陆地, 目的是寻找边界

过程

  • 二维数组, 长/宽度:grid[0].length, 高:grid.length
  • for循环遍历所有的点
  • 如果是水就放过, 如果为陆地就dfs
  • 一个dfs结束证明完成了一个岛屿,count++
dfs过程
  • base case : 出界,或, 已经为水
  • recursion过程中每路过一个点(dfs中当然这个点为陆地点), 就将这个点变为水,以表明已经计算过这个点
  • 如何让dfs中的点走起来? 建立坐标系,for循环实现
int[] dx = {0, 1, 0, -1};
int[] dy = {1, 0, -1, 0};
dfs(char[] g, int i, int j){
    for(int k = 0; k < 4; k++){
        dfs(g, i + dx[k], j + dy[k]);
    }
}

复杂度

  • 时间: O(mn) 主函数里的双层loop
  • 空间: 最坏为O(mn), 当dfs遍历了所有的点,意味着二维数组开始全部为陆地

代码

class Solution {
    int[] dx = {0, 1, 0 ,-1};
    int[] dy = {1, 0, -1, 0};
    public int numIslands(char[][] grid) {
        //corner case
        if(grid == null || grid.length == 0 || grid[0].length == 0)
            return 0;
        
        int length = grid.length;
        int height = grid[0].length;
        int res = 0;
        for(int i = 0; i < length; i++){
            for(int j = 0; j < height; j++){
                if(grid[i][j] == '1'){
                    dfs(grid, i, j);
                    res++;
                }
            }
        }
        return res;
    }
    
    private void dfs(char[][] grid, int i, int j){
        if(i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == '0') return;
        grid[i][j] = '0';
        for(int k = 0; k < 4; k++){
            dfs(grid, i + dx[k], j + dy[k]);
        }
    }
}