695. Max Area of Island (Medium)——岛屿的最大面积

本文介绍了一种利用深度优先搜索(DFS)算法解决寻找二维数组中最大岛屿面积问题的方法。通过遍历矩阵,对每个可能的岛屿进行DFS遍历,计算其面积并与已知最大值比较,最终得出最大岛屿面积。

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

前言:

本题目为深度优先遍历(DFS) 算法的一道典型例题。 

 

题目 :

给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合。你可以假设二维矩阵的四个边缘都被水包围着。

找到给定的二维数组中最大的岛屿面积。(如果没有岛屿,则返回面积为0。)

示例 1:

[[0,0,1,0,0,0,0,1,0,0,0,0,0],
 [0,0,0,0,0,0,0,1,1,1,0,0,0],
 [0,1,1,0,1,0,0,0,0,0,0,0,0],
 [0,1,0,0,1,1,0,0,1,0,1,0,0],
 [0,1,0,0,1,1,0,0,1,1,1,0,0],
 [0,0,0,0,0,0,0,0,0,0,1,0,0],
 [0,0,0,0,0,0,0,1,1,1,0,0,0],
 [0,0,0,0,0,0,0,1,1,0,0,0,0]]
对于上面这个给定矩阵应返回 6。注意答案不应该是11,因为岛屿只能包含水平或垂直的四个方向的‘1’。

示例 2:

[[0,0,0,0,0,0,0,0]]
对于上面这个给定的矩阵, 返回 0。

注意: 给定的矩阵grid 的长度和宽度都不超过 50。

 

解题算法: 

 

DFS:

 

广度优先搜索一层一层遍历,每一层得到的所有新节点,要用队列存储起来以备下一层遍历的时候再遍历。

而深度优先搜索在得到一个新节点时立即对新节点进行遍历:从节点 0 出发开始遍历,得到到新节点 6 时,立马对新节点 6 进行遍历,得到新节点 4;如此反复以这种方式遍历新节点,直到没有新节点了,此时返回。返回到根节点 0 的情况是,继续对根节点 0 进行遍历,得到新节点 2,然后继续以上步骤。

从一个节点出发,使用 DFS 对一个图进行遍历时,能够遍历到的节点都是从初始节点可达的,DFS 常用来求解这种 可达性问题。

在程序实现 DFS 时需要考虑以下问题:

  • 栈:用栈来保存当前节点信息,当遍历新节点返回时能够继续遍历当前节点。可以使用递归栈。
  • 标记:和 BFS 一样同样需要对已经遍历过的节点进行标记。

 

思路:

 最外层用两个for循环对grid[][]数组的每个元素进行遍历,如果元素值为0,则continue跳过。如果值为1则说明可达,就对其进行深度优先遍历,找到以该元素为起点的岛屿的最大面积,并与之前的maxArea作比较,取最大值。当所有元素都遍历完之后,也就得到了最终的最大值。

对方法findMax的描述是:该方法接收一个坐标position,既然这个坐标传了过来,说明这个点是符合要求的,先令maxArea=1。然后对这个点进行四个方向的移动,得到移动后不符合要求的点就continue跳过,如果符合要求就对改点再进行深度优先遍历,并让maxArea加上改点进行深度优先遍历的到的最大面积。

这里虽然用的是递归,没有用到上文所说的“栈”,但二者起的作用却是一样的,递归的调用与“栈”的思想极为相似,感兴趣的童鞋也可以试试用Stack结合循环来解题~

 

 代码:

 

public class MaxAreaOfIsland {
    private int m, n;
    int[][] directions = {{1, 0},{-1, 0},{0, 1},{0, -1}};

    public int maxAreaOfIsland(int[][] grid) {
        if (grid == null || grid.length==0) return 0;
        int maxArea = 0;
        m = grid.length;
        n = grid[0].length;
        for (int i = 0; i < grid.length; i++) {
            for (int j = 0; j < grid[0].length; j++) {
                if (grid[i][j] == 0) continue;
                maxArea = Math.max(maxArea, findMax(grid, new Pair(i,j)));
            }
        }
        return maxArea;
    }

    public int findMax(int[][] grid, Pair<Integer, Integer> position) {
        int maxArea = 1;
        int r = position.getKey(), c = position.getValue();
        grid[r][c] = 0;
        for (int[] direction : directions) {
            int cr = r + direction[0];
            int cc = c + direction[1];
            if (cr < 0 || cr >= m || cc < 0 || cc >= n || grid[cr][cc]==0) continue;
            maxArea += findMax(grid, new Pair(cr, cc));
        }
        return maxArea;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

请保持优秀。

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

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

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

打赏作者

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

抵扣说明:

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

余额充值