LeetCode 695. 岛屿的最大面积c++/java详细题解
Posted 林深时不见鹿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 695. 岛屿的最大面积c++/java详细题解相关的知识,希望对你有一定的参考价值。
1、题目
给定一个包含了一些 0
和 1
的非空二维数组 grid
。
一个 岛屿 是由一些相邻的 1
(代表土地) 构成的组合,这里的「相邻」要求两个 1
必须在水平或者竖直方向上相邻。你可以假设 grid
的四个边缘都被 0
(代表水)包围着。
找到给定的二维数组中最大的岛屿面积。(如果没有岛屿,则返回面积为 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。
2、思路
(DFS) O ( n ∗ m ) O(n*m) O(n∗m)
给定一个由0
和1
组成的二维数组grid
,其中1
代表岛屿土地,要求找出二维数组中最大的岛屿面积,没有则返回0
。
样例:
如样例所示,二维数组grid
的最大岛屿面积为4
,下面来讲解深度优先搜索的做法。
我们定义这样一种搜索顺序,即先搜索岛屿上的某块土地,然后以4
个方向向四周探索与之相连的每一块土地,搜索过程中维护一个area
变量,用来记录搜索过的土地总数。为了避免重复搜索,在这个过程中需要将已经搜索过的土地置为0
,最后我们返回最大的area
即可。
搜索函数设计:
int dfs(int x, int y)
x
,y
是当前搜索到的二维数组grid
的横纵坐标。
实现细节:
- 1、为了确保每个位置只被搜索一次,从当前搜索过的位置继续搜索下一个位置时,需要对当前位置进行标识,表示已经被搜索。
- 2、将二维数组
grid
以及二维数组的行数n
和列数m
都定义为全局变量可以减少搜索函数dfs
的参数数量。 - 3、使用偏移数组来简化代码,如下图所示:
具体过程如下:
- 1、定义
res = 0
,遍历grid
数组。 - 2、如果当前
grid
数组元素grid[i][j] == 1
,也就是说为土地的话,就以当前土地(i,j)
为起点继续向四周搜索联通的土地。 - 3、直到搜索完当前土地的所有的连通土地,最后将连通土地总数记录到
area
中。 - 4、执行
res = max(res,area)
,不断更新答案。
时间复杂度分析: O ( n ∗ m ) O(n*m) O(n∗m), n n n是二维数组的行数, m m m是二维数组的列数,每个位置只被搜索一次。
3、c++代码
class Solution {
public:
int n, m;
vector<vector<int>>g;
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; //偏移数组
int dfs(int x, int y) //搜索函数
{
int area = 1;
g[x][y] = 0; //已经搜索过,标记为0
for(int i = 0; i < 4; i++)
{
int a = x + dx[i], b = y + dy[i];
//当前土地未出界也未被搜索过,继续下一层搜索
if(a >=0 && a < n && b >=0 && b < m && g[a][b])
area += dfs(a, b);
}
return area; //返回连通土地总数
}
int maxAreaOfIsland(vector<vector<int>>& grid) {
g = grid;
int res = 0;
n = grid.size(), m = grid[0].size();
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
if(g[i][j])
res = max(res,dfs(i,j));
return res;
}
};
4、java代码
class Solution {
private int n, m;
private int[][] g;
private int[] dx = {-1, 0, 1, 0}, dy = {0, 1, 0, -1};//偏移数组
public int dfs(int x, int y) //搜索函数
{
int area = 1;
g[x][y] = 0; //已经搜索过,标记为0
for(int i = 0; i < 4; i++)
{
int a = x + dx[i], b = y + dy[i];
//当前土地未出界也未被搜索过,继续下一层搜索
if(a >=0 && a < n && b >= 0 && b < m && g[a][b] != 0)
area += dfs(a, b);
}
return area; //返回连通土地总数
}
public int maxAreaOfIsland(int[][] grid) {
g = grid;
int res = 0;
n = grid.length; m = grid[0].length;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
if(g[i][j] != 0)
res = Math.max(res,dfs(i,j));
return res;
}
}
原题链接: 695. 岛屿的最大面积
以上是关于LeetCode 695. 岛屿的最大面积c++/java详细题解的主要内容,如果未能解决你的问题,请参考以下文章