695.岛屿的最大面积
题目描述
给你一个大小为 m x n m x n mxn 的二进制矩阵 g r i d grid grid 。
岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。
岛屿的面积是岛上值为 1 的单元格的数目。
计算并返回 grid 中最大的岛屿面积。如果没有岛屿,则返回面积为 0 。
样例 #1
样例输入 #1
grid = [[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]]
样例输出 #1
6
样例 #2
样例输入 #2
grid = [[0,0,0,0,0,0,0,0]]
样例输出 #2
0
提示
m = = g r i d . l e n g t h n = = g r i d [ i ] . l e n g t h 1 < = m , n < = 50 g r i d [ i ] [ j ] 为 0 或 1 。 m == grid.length\\ n == grid[i].length\\ 1 <= m, n <= 50\\ grid[i][j] 为 0 或 1。 m==grid.lengthn==grid[i].length1<=m,n<=50grid[i][j]为0或1。
做题思路
拿到这道题可以说是熟悉BFS的狂喜了。
因为BFS对邻接跑遍历是很友好的。
不太熟悉也不要紧。
这道题的要点就在于如何算出每一个岛屿的面积,从而选择最大。
因为岛屿 是由一些相邻的 1 (代表土地/陆地) 构成的组合,那么如果现已知其中一块陆地,如何算出该陆地所在的岛屿大小是重点问题。
如果已知一块陆地,那遍历这块陆地相邻的土地,都是同一岛屿上的陆地。
再将其他的陆地做同样的操作,就可以知道该陆地相邻的陆地。
为了防止重复访问已知陆地可以做个标记。
官方解释:
- 我们想知道网格中每个连通形状的面积,然后取最大值。
- 如果我们在一个土地上,以 4 个方向探索与之相连的每一个土地(以及与这些土地相连的土地),那么探索过的土地总数将是该连通形状的面积。
- 为了确保每个土地访问不超过一次,我们每次经过一块土地时,将这块土地的值置为 0。这样我们就不会多次访问同一土地。
总思路
- 遍历每一个地
- 如果是土地,探索以 4 个方向探索与之相连的每一个土地(以及与这些土地相连的土地),最后得出该岛屿面积
- 取最大的岛屿
时间复杂度分析
跑完全图 O ( n × m ) O(n\times m) O(n×m)
伪代码
代码
class Solution {
public:
int maxAreaOfIsland(vector<vector<int>>& grid) {
int vis[50][50] = {false};
int ans = 0;
int bt[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
for(int i=0;i<grid.size();i++){
for(int j=0;j<grid[i].size();j++){
if(grid[i][j] && !vis[i][j]){
queue<pair<int,int > > q;
q.push(make_pair(i,j));
vis[i][j] = true;
int sum = 1;
while(!q.empty()){
int x,y;
tie(x,y) = q.front();
q.pop();
for(int i=0;i<4;i++){
int nx = x + bt[i][0];
int ny = y + bt[i][1];
if(nx>=0 && ny>=0 && ny<grid[0].size() && nx<grid.size() && grid[nx][ny] && !vis[nx][ny]){
vis[nx][ny] = true;
sum++;
q.push(make_pair(nx,ny));
}
}
}
ans = max(sum,ans);
}
}
}
return ans;
}
};