题意理解
地图是一个矩阵,每个格子里面是0或者1。格子的上下左右视为相邻,即连在一起。要求最大的岛屿面积就是求连在一起的1的个数最多是多少。
方法一
深度优先搜索
对于每一个格子,我们有上下左右四个方向,如果相邻的格子是1,那么就可以向这个方向移动,面积加1。
我们使用pass数组记录每个格子是否遍历过,没有遍历过且值为1的格子才可以走上去,否则都不行。注意这里不是在寻找路径,所以在递归后pass不回退,否则会导致面积计算错误。
在主程序中,我们遍历矩阵grid,遇到格子值为1就进行一次dfs,得到一个连在一起的1的个数,更新一次最大值。
演示过程如下,红点表示当前所在位置:
具体代码如下:
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param grid int整型vector<vector<>>
* @return int整型
*/
int x[4] = {-1,1,0,0};
int y[4] = {0,0,-1,1};
int s = 0;
vector<vector<bool>> pass;
void dfs(vector<vector<int>>& grid, int i, int j) {
for (int k=0;k<4;k++)
{
//注意边界
if (i+x[k]>-1 && i+x[k]<grid[0].size() &&
j+y[k]>-1 && j+y[k]<grid.size() &&
pass[i+x[k]][j+y[k]]==false &&
grid[i+x[k]][j+y[k]] == 1)
{
pass[i+x[k]][j+y[k]] = true;
s++;
dfs(grid, i+x[k], j+y[k]);
}
}
return;
}
int maxAreaIsland(vector<vector<int> >& grid) {
// write code here
int ans = 0;
vector<bool> temp;
//初始化pass
for (int i=0;i<grid[0].size();i++)
temp.push_back(false);
for (int i=0;i<grid.size();i++)
pass.push_back(temp);
//遍历grid
for (int i=0;i<grid.size();i++)
{
for (int j=0;j<grid[0].size();j++)
{
if (grid[i][j])
{
//当前位置pass设置为true
pass[i][j] = true;
s = 1;
dfs(grid, i, j);
ans = max(ans, s);
}
}
}
return ans;
}
};
时间复杂度: 。由于pass没有回退,每一块岛屿仅被扫描一遍,所以每一个格子都被扫描过一遍且仅被扫描过一遍。
空间复杂度: 。开辟了新的数组pass,大小和grid一致;递归栈的深度也为NM。
方法二
宽度优先搜索
额外使用一个队列实现宽度优先搜索,以起点为中心向四周探查相邻的格子值是否为1。其余的注意点和深度优先搜索一致。
具体代码如下:
class Solution {
public:
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
*
* @param grid int整型vector<vector<>>
* @return int整型
*/
int x[4] = {-1,1,0,0};
int y[4] = {0,0,-1,1};
int s = 0;
queue<pair<int,int>> q;
vector<vector<bool>> pass;
void bfs(vector<vector<int>>& grid, int i, int j) {
//坐标(i,j)周围的格子没有扫描过,那么它就要先进入队列
q.push({i,j});
while (!q.empty())
{
//从队列头部弹出
auto coordinate = q.front();
q.pop();
for (int k=0;k<4;k++)
{
int xx = coordinate.first + x[k], yy = coordinate.second +y[k];
if (xx>-1 && xx<grid.size() && yy>-1 && yy<grid[0].size()
&& pass[xx][yy]==false && grid[xx][yy])
{
pass[xx][yy] = true;
s++;
bfs(grid, xx, yy);
}
}
}
return;
}
int maxAreaIsland(vector<vector<int> >& grid) {
// write code here
int ans = 0;
vector<bool> temp;
//初始化pass
for (int i=0;i<grid[0].size();i++)
temp.push_back(false);
for (int i=0;i<grid.size();i++)
pass.push_back(temp);
//遍历grid
for (int i=0;i<grid.size();i++)
{
for (int j=0;j<grid[0].size();j++)
{
if (grid[i][j])
{
//当前位置pass设置为true
pass[i][j] = true;
s = 1;
bfs(grid, i, j);
ans = max(ans, s);
}
}
}
return ans;
}
};
时间复杂度: 。由于pass没有回退,每一块岛屿仅被扫描一遍,所以每一个格子都被扫描过一遍且仅被扫描过一遍。
空间复杂度: 。开辟了新的数组pass,大小和grid一致;队列q的长度也为格子的总数。