算法题:求岛屿的数量 java - Kaiqisan

本文讲解如何利用递归的深搜方法解决二维数组中岛屿计数问题,通过遍历和标记实现,同时提示在大数据量下内存消耗的注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

大家好,都吃晚饭了吗?我是Kaiqisan,是一个已经走出社恐的一般生徒,今天爷又回来了,继续昨天的并查集,来结合例题讲讲深搜的奇妙用法

问题

如图,求岛的数量

{0, 0, 1, 0, 1, 0}
{1, 1, 1, 0, 1, 0}
{1, 0, 0, 1, 0, 0}
{0, 0, 0, 0, 0, 0}

图中 0 代表海洋,1代表陆地(PS:陆地直接无法通过斜对角的陆地来直接连接)
所以图中一共有3块陆地

思路

先进行遍历,对所有的数组成员进行遍历,如果碰到一块陆地就使用递归进行深搜,在深搜的时候如果碰到旁边是陆地的话就进行标记,在后面的遍历以及深搜的过程中都会被忽视

就以上面的那个二位数组为例

{0, 0, 1, 0, 1, 0}
{1, 1, 1, 0, 1, 0}
{1, 0, 0, 1, 0, 0}
{0, 0, 0, 0, 0, 0}

我们开始像读书一样,从左往右从上往下遍历,我们首先看到了第一行第三个元素为1,所以,我们从这里开始深搜,并做标记(把所有遍历到符合条件的元素),深搜完成,岛的总数+1

{0, 0, 2, 0, 1, 0}
{2, 2, 2, 0, 1, 0}
{2, 0, 0, 1, 0, 0}
{0, 0, 0, 0, 0, 0}

第二次找到陆地

{0, 0, 2, 0, 2, 0}
{2, 2, 2, 0, 2, 0}
{2, 0, 0, 1, 0, 0}
{0, 0, 0, 0, 0, 0}

…以此类推

就这样我们完成所有的遍历之后,返回累计发现的岛的数量

代码

	static int doFind(int[][] island) {
        int res = 0;
        for (int i = 0; i < island.length; i++) {
            for (int j = 0; j < island[0].length; j++) {
                if (island[i][j] == 1) {
                    res++;
                    doInfect(island, i, j);
                }
            }
        }
        return res;
    }

    static void doInfect(int[][] island, int i, int j) {
        int hei = island.length;
        int wid = island[0].length;
		
		// 不符合条件的全部驳回(越界,重复遍历,找到海洋)
        if (i < 0 || i >= hei || j < 0 || j >= wid || island[i][j] != 1) {
            return;
        }
        island[i][j] = 2;
        doInfect(island, i + 1, j);
        doInfect(island, i - 1, j);
        doInfect(island, i, j + 1);
        doInfect(island, i, j - 1);

    }

总结

没有总结,建议在合适的地方使用深搜,在数据量大的时候还是很耗内存的(今天写力扣使用深搜就直接内存爆炸了)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

kaiqisan

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

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

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

打赏作者

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

抵扣说明:

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

余额充值