岛屿的最大问题求解

一、LeetCode 200—中等难度

本人一直没有好好理清这道leetCode应该如何求解,考虑到不能带着疑惑伴随终身,因此给出这道题的分析与求解过程

题干描述

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

示例 1:

输入:
11110
11010
11000
00000

输出: 1
示例 2:

输入:
11000
11000
00100
00011

输出: 3

分析与求解思路

本人一直苦恼于二维矩阵的不规则遍历和上下左右四个数值的判断,因此每次做到这道题的时候会产生碰壁、无从下手的情况,但程序本就可以将相同的操作循环化,相似的分治操作递归化。因此,提供第一个思路就是将矩阵的规模不断缩小
缩小矩阵的规模有拆分矩阵做递归的方式,我们称之为图的遍历,真正的问题点在于如何将二维矩阵转换成图结构,转换成为图结构之后就可以使用dfs的深度优先遍历法。本人看题解发现针对这道题还有BFS广度优先遍历法,但是相较之下还是深度优先方式的递归更加简单,下面给出伪码实现:

class Solution {
    void dfs(char[][] grid, int r, int c) {
        int nr = grid.length;
        int nc = grid[0].length;
        if (r < 0 || c < 0 || r >= nr || c >= nc || grid[r][c] == '0') {
            return;
        }
        grid[r][c] = '0';//将原本为1的元素修改为'0'
        dfs(grid, r - 1, c); //遍历上下左右四个方向
        dfs(grid, r + 1, c);
        dfs(grid, r, c - 1);
        dfs(grid, r, c + 1);
    }

    public int numIslands(char[][] grid) {
        if (grid == null || grid.length == 0) {
            return 0;
        }
        int nr = grid.length;
        int nc = grid[0].length;
        int num_islands = 0;
        for (int r = 0; r < nr; ++r) {
            for (int c = 0; c < nc; ++c) {
                if (grid[r][c] == '1') {
                    ++num_islands;
                    dfs(grid, r, c);//将‘1’周边的‘1’修改为‘0’
                }
            }
        }
        return num_islands;
    }
}

代码解释与说明

核心求解在于孤岛的数量遍历,如果只有一个孤岛的情况下,沿着一个起点进行深度优先遍历是可以把所有陆地节点“1” 修改为 海水节点 “0”,因此如果统计出来一个岛屿后,仍然有 陆地 节点1,说明我们的程序没有统计完二维矩阵中的孤岛节点,说明给出的矩阵中不止一个岛屿,因此我们要把 修改后的上下左右的位置的陆地再下钻,深度优先遍历 上一次的节点的四个邻居,继续这个置 陆地“1” 为海水 “0” 的过程 ,所以对于外层循环来说,仍然至少存在 1个这个的陆地节点,这个时候我们处理这个 陆地节点之前,对岛屿的数量增加1,就可以统计出来上一次遗漏的组成岛屿的碎片 陆地,直到双层循环完毕之后,最终可以求得岛屿的数量

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值