0
点赞
收藏
分享

微信扫一扫

LeetCode 200.岛屿数量

RJ_Hwang 2023-08-18 阅读 47

1.题目:

给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

 

示例 1:

输入:grid = [
  ["1","1","1","1","0"],
  ["1","1","0","1","0"],
  ["1","1","0","0","0"],
  ["0","0","0","0","0"]
]
输出:1

示例 2:

输入:grid = [
  ["1","1","0","0","0"],
  ["1","1","0","0","0"],
  ["0","0","1","0","0"],
  ["0","0","0","1","1"]
]
输出:3



2.代码:

dfs:

class Solution {
    public int numIslands(char[][] grid) {
        int num = 0;//计算岛屿的数量
        for(int i=0;i<grid.length;i++){
            for(int j=0;j<grid[0].length;j++){
                if(grid[i][j]=='1'){//当遇到1的时候
                    num++;//岛屿数量++
                    dfs(grid,i,j);//此时用dfs把整一块岛屿的1变成0
                }
            }
        }
        return num;
    }
    public void dfs(char[][] grid,int i,int j){
        if(i<0 || j<0 || i>=grid.length || j>=grid[0].length || grid[i][j]=='0') return;//递归的出口
        grid[i][j]='0';//实际操作,把1变成0
        dfs(grid,i-1,j);//这就是把水平方向和/或竖直方向上的1变成0
        dfs(grid,i,j-1);
        dfs(grid,i+1,j);
        dfs(grid,i,j+1);
    }
}




bfs:

lass Solution {
    boolean[][] visited ;//标记访问过的节点,不要重复访问
    int[][] move = {{0,1},{0,-1},{1,0},{-1,0}};//表示四个方向
    public int numIslands(char[][] grid) {
        int res = 0;
        visited = new boolean[grid.length][grid[0].length];
        for(int i=0;i<grid.length;i++){
            for(int j=0;j<grid[0].length;j++){
                if(!visited[i][j] && grid[i][j]=='1'){//这个条件始终不明白,为什么是true好奇怪
                    bfs(grid,i,j);
                    res++;
                }
            }
        }
        return res;
    }
    public void bfs(char[][] grid,int x,int y){
        Deque<int[]> queue = new ArrayDeque<>();//定义队列
        queue.offer(new int[]{x,y});//起始节点加入队列
        visited[x][y]=true;//只要加入队列,就立即标记为访问过的节点
        while(!queue.isEmpty()){//开始遍历队列里面的元素
            int[] cur = queue.poll();//把队列里的数组元素取出来
            int m = cur[0];
            int n = cur[1];
            for(int i=0;i<move.length;i++){//开始向当前结点的四个方向上下左右遍历
                int nextm = m+move[i][0];
                int nextn = n+move[i][1];//获取四个方向的坐标
                if(nextm<0 || nextn<0 || nextm>=grid.length || nextn>=grid[0].length) continue;//坐标越界了,直接跳过
                if(!visited[nextm][nextn] && grid[nextm][nextn]=='1'){//如果节点没被访问过
                    queue.offer(new int[]{nextm,nextn});//队列添加该节点为下一轮要遍历的节点
                    visited[nextm][nextn] = true;//只要加入队列立即被标记,避免重复访问
                }
            }
        }
    }
}








举报

相关推荐

0 条评论