Leetcode 200. 岛屿数量

好久没写文章的我来水一篇了。
今天带来的是Leetcode200 的一题,难度中等。
先上题目。

给定一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。你可以假设网格的四个边均被水包围。
示例 1:
输入:
11110
11010
11000
00000
输出: 1
示例 2:
输入:
11000
11000
00100
00011
输出: 3

题意简单明了,思路也很容易有,最起码的可以dfs搜索配合染色,,更有技术含量的可以是并查集,其实我觉得这里得染色和并查集倒是一种原理,但是并查集显然会很妙。
并查集还是一种很有意思得算法,粗略记录一下自己得心得。
两个不同的点,因为某种原因联系了起来,于是用一条连来连接。越来越多得点,有的有联系,有的无联系,这时候就像是一个个派别,互相有关联得点联合在一起,变成了一棵树,
于是产生了几个派别,如果这时候发现一个派别下得一个点,和另一个派别可以有联系,那就可以强强联合,将此派别并入另一个派别下,成为了一体。
我们需要的是找每一个派别的老大,即祖结点。我们可以通过压缩路径来缩减时间复杂度。因为我们不必把每一个新找到的点并在子节点以下,这样互相查找会花更多时间,我们找到祖结点然后直接把它并入祖结点以下,这样到了最后,我们的一棵树只有两层了,祖结点和叶节点。。
如这题,两个1之间如果有联系,直接并成一棵树,最后看有几棵树就是答案了。
那么怎么并呢,我们需要查找到每一个节点的祖结点,如果他们的祖结点是一样,就不用并了,已经是一棵树。如果不一样,那么将其中一个祖结点变成另一个的子节点,注意处理后要压缩路径

我没有用并查集写,但是效率也不算低了。
讲下我的思路,找到一个1直接res + 1,而后从这个1开始,将所有与它有关的1变为0,因为他们不可以算在res里面。非常简单,很容易看懂!
以下是在leetcode通过的Java代码。

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') {
                    res += 1;
                    dfs(i, j, grid);
                }
            }
        }
        return res;
    }
    public void dfs(int x, int y, char[][] grid) {
        grid[x][y] = '0';
        if(x > 0 && grid[x - 1][y] == '1') {
            dfs(x - 1, y, grid);
        }
        if(y > 0 && grid[x][y - 1] == '1') {
            dfs(x, y - 1, grid);
        }
        if(x < grid.length - 1 && grid[x + 1][y] == '1') {
            dfs(x + 1, y, grid);
        }
        if(y < grid[0].length - 1 && grid[x][y + 1] == '1') {
            dfs(x, y + 1, grid);
        }
    }
}

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值