leetcode.200. 岛屿数量---DFS+记忆化

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'

题解:

我们可以将求解岛屿数量看成求解被同一个母体感染源感染的区域数量。

  • 遍历grid数组,一旦遍历到一个元素为‘1’,则对其向上下左右四个方向“感染”,且如果被“感染”的位置本来元素值为‘1’,则认为是感染成功,所以‘1’改为‘2’;若本来被“感染”的位置本来元素值为‘0’,则认为感染失败,所以‘0’不会改变。依照此思路进行深搜即可,注意边界问题即深搜结束条件即可。

注意的是,我们为什么要对“感染”成功的进行修改值呢?

  • 因为我们不想让岛屿数量重复计算,即通过感染后修改值,使得遍历时不会再进行“重复感染”了,因为已经认为其感染过了。

另外有人会想,为什么要向四个方向感染呢?直接向右和向下感染好像就足够了啊!
反例:

 ["2","2","2"]
 ["0","2","0"]
 ["1","2","2"]
  • 这时发现感染到最后左边的1会重复计算,但其实其是属于同一个母体感染源感染的!
  • 并且还要注意的是在dfs方法中的if判断中,最后一个判断必须要为grid[i][j]!='1'!!!因为由于“感染”,导致被感染的‘1’都变成‘2’了,因此若碰到‘2’也是要停止的,因为这是已经感染过的,所以如果if中的判断只为grid[i][j]!='0',那么‘2’会重复计算。

代码:

class Solution {
    public int numIslands(char[][] grid) {
        int res = 0;
        
        for(int i=0;i<grid.length;i++){
            for(int j=0;j<grid[0].length;j++){

                if(grid[i][j]=='1'){
                    dfs(grid,i,j);
                    res++;
                }
                
            }
        }

        return res;
    }

    public void dfs(char[][] grid,int i,int j){
        if(i<0 || j<0 ||
            i>grid.length-1 || j>grid[0].length-1 || grid[i][j]!='1'){
            return;
        }

        grid[i][j] = '2';

        dfs(grid,i+1,j);
        dfs(grid,i,j+1);
        dfs(grid,i-1,j);
        dfs(grid,i,j-1);



    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

向光.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值