30.岛屿数量(medium)

1.题目链接:200. 岛屿数量 - 力扣(LeetCode)200. 岛屿数量 - 给你一个由 '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 提示: * m == grid.length * n == grid[i].length * 1 <= m, n <= 300 * grid[i][j] 的值为 '0' 或 '1'https://leetcode.cn/problems/number-of-islands/description/

2.题目描述:

给你一个由 '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​​
提示:

m == grid.length

n == grid[i].length

1 <= m, n <= 300

grid[i][j]  的值为 '0' 或 '1'​

算法思路:
遍历整个矩阵,每次找到「一块陆地」的时候:

说明找到「一个岛屿」,记录到最终结果 ret  里面;​
并且将这个陆地相连的所有陆地,也就是这块「岛屿」,全部「变成海洋」。这样的话,我们下次

遍历到这块岛屿的时候,它「已经是海洋」了,不会影响最终结果。

其中「变成海洋」的操作,可以利用「深搜」和「宽搜」解决,其实就是 733. 图像渲染 这道题~​

这样,当我们,遍历完全部的矩阵的时候,ret  存的就是最终结果。​

解法(dfs):​
算法流程:
1. 初始化ret = 0 ,记录目前找到的岛屿数量;​
2. 双重循环遍历二维网格,每当遇到一块陆地,标记这是一个新的岛屿,然后将这块陆地相连的陆地   全部变成海洋。

递归函数的设计:
1. 把当前格子标记为水;
2. 向上、下、左、右四格递归寻找陆地,只有在下标位置合理的情况下,才会进入递归:                

         a. 下一个位置的坐标合理;
         b. 并且下一个位置是陆地​

Java算法代码:

class Solution {
    boolean [][] vis;
    int m,n;
    int []dx = {0,0,-1,1};
    int []dy = {1,-1,0,0};
    public int numIslands(char[][] grid) {
        m = grid.length; n = grid[0].length;
        vis = new boolean[m][n];

        int ret = 0;
        for(int i = 0; i< m;i++)
            for(int j = 0; j<n;j++)
                if(!vis[i][j] && grid[i][j] =='1'){
                    ret++;
                    dfs(grid,i,j);
                }
        return ret;
    }
    public void dfs(char[][] grid,int i,int j){
        vis[i][j] =true;
        for(int k = 0; k<4;k++){
            int x = i + dx[k], y = j + dy[k];
            if(x >= 0 && x < m && y >= 0 && y < n && !vis[x][y] && grid[x][y]== '1')
                dfs(grid,x,y);
        }
    }
}

运行结果:

递归展开:

逻辑展开:

这里逻辑很好理解,一个细节在于,将岛屿变为海洋。

当能理解细节时候,就可以手撸结果了。

---------------------------------------------------------------------------------------------------------------------------------

记住,相信你的递归函数,它可以做到!

记住,不理解时候,去尝试手动展开!

记住,逻辑展开(你不可能对所有的题目都进行手动展开)!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值