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

秒速五厘米 2023-05-31 03:21 102阅读 0赞

前言:

本题目为深度优先遍历(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:

format_png

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

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

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

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

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

思路:

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

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

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

代码:

  1. public class MaxAreaOfIsland {
  2. private int m, n;
  3. int[][] directions = {
  4. {1, 0},{-1, 0},{0, 1},{0, -1}};
  5. public int maxAreaOfIsland(int[][] grid) {
  6. if (grid == null || grid.length==0) return 0;
  7. int maxArea = 0;
  8. m = grid.length;
  9. n = grid[0].length;
  10. for (int i = 0; i < grid.length; i++) {
  11. for (int j = 0; j < grid[0].length; j++) {
  12. if (grid[i][j] == 0) continue;
  13. maxArea = Math.max(maxArea, findMax(grid, new Pair(i,j)));
  14. }
  15. }
  16. return maxArea;
  17. }
  18. public int findMax(int[][] grid, Pair<Integer, Integer> position) {
  19. int maxArea = 1;
  20. int r = position.getKey(), c = position.getValue();
  21. grid[r][c] = 0;
  22. for (int[] direction : directions) {
  23. int cr = r + direction[0];
  24. int cc = c + direction[1];
  25. if (cr < 0 || cr >= m || cc < 0 || cc >= n || grid[cr][cc]==0) continue;
  26. maxArea += findMax(grid, new Pair(cr, cc));
  27. }
  28. return maxArea;
  29. }
  30. }

发表评论

表情:
评论列表 (有 0 条评论,102人围观)

还没有评论,来说两句吧...

相关阅读