二维数组里,1代表陆地,0代表海洋。
我们最多只能将一个0(海洋)变成1(陆地)。
进行填海后,地图上最大的岛屿面积是多少?(上、下、左、右四个方向相连的1可形成岛屿)
例如:[[1,0],[0,1]],最大岛屿面积是3(将其中一个0变成1)
思路1:
1、将其中一个位置0变成1,然后在该位置进行深搜,另外用一个数组作为标记位,深搜的过程中统计陆地的个数,既是岛的面积。
代码如下:
class Solution {
public:
int a[50][50];//标记位
void clear(int X,int Y)//标记为清零
{
for(int i=0;i<X;i++)
{
for(int j=0;j<Y;j++)
{
a[i][j]=0;
}
}
}
void search(vector<vector<int>>& grid,int x,int y,int& sum)//深搜,x y为位置,sum为大陆的个数
{
int X=grid.size();
int Y=grid[0].size();
if(grid[x][y]==1&&a[x][y]==0)
{
sum++;
a[x][y]=1;
if(x-1>=0) search(grid,x-1,y,sum);//四个方向
if(x+1<X) search(grid,x+1,y,sum);
if(y-1>=0) search(grid,x,y-1,sum);
if(y+1<Y) search(grid,x,y+1,sum);
}
}
int largestIsland(vector<vector<int>>& grid) {
int X=grid.size();
int Y=grid[0].size();
int i,j;
int sum,max=0;
for(i=0;i<X;i++)
{
for(j=0;j<Y;j++)
{
if(grid[i][j]==0)
{
grid[i][j]=1;//填海
clear(X,Y);
sum=0;
search(grid,i,j,sum);
grid[i][j]=0;//不填海
if(max<sum)max=sum;
}
}
}
if(max==0) max=X*Y;//没有海,只有陆地的情况
return max;
}
};
思路2:
1、思路1中,每次找到一个0,都要进行一次深搜,那可不可以简化一下呢。
2、对于每一个0(海),只要知道它上下左右四个方向的岛的面积,就可以通过相加,获得填海后的大岛的面积。
3、问题就在于,对于每一个0(海),怎么知道它上下左右四个方向的岛是同一个岛,还是不相同的岛。
4、于是,首先先对岛分类编号,同时统计不同岛的面积。
代码如下:
class Solution {
public:
int a[50][50]={0};//对岛分类编号
int area[700]={0};//不同编号的岛对应不同的面积
int islandnum=0;//编号
void search(vector<vector<int>>& grid,int x,int y)
{
int X=grid.size();
int Y=grid[0].size();
if(grid[x][y]==1&&a[x][y]==0)
{
area[islandnum]++;//累计相同编号的岛的陆地
a[x][y]=islandnum;//给陆地附上编号
if(x-1>=0) search(grid,x-1,y);//四个方向
if(x+1<X) search(grid,x+1,y);
if(y-1>=0) search(grid,x,y-1);
if(y+1<Y) search(grid,x,y+1);
}
}
int largestIsland(vector<vector<int>>& grid) {
int X=grid.size();
int Y=grid[0].size();
for(int i=0;i<X;i++)
{
for(int j=0;j<Y;j++)
{
if(grid[i][j]==1&&a[i][j]==0)
{
islandnum++;//找到的第一个岛,应该从编号1开始
search(grid,i,j);
}
}
}
int b[4]={0};//海的四个方向的岛的编号,上下左右
int maxsum=0,sum;
for(int i=0;i<X;i++)
{
for(int j=0;j<Y;j++)
{
if(grid[i][j]==0)
{
sum=1;//毕竟填海嘛,面积得从1算起
if(i-1<0) b[0]=0;
else b[0]=a[i-1][j];//上没有越界,则附值上方的岛的编号
if(i+1>=X) b[1]=0;
else b[1]=a[i+1][j];//同理
if(j-1<0) b[2]=0;
else b[2]=a[i][j-1];//同理
if(j+1>=Y) b[3]=0;
else b[3]=a[i][j+1];//同理
for(int k=0;k<4;k++)
{
if(b[k]!=0)
{
sum+=area[b[k]];//加上该方向的岛的编号的面积
for(int l=k+1;l<4;l++)
{
if(b[l]==b[k]) b[l]=0;//保证四个方向不会出现相同编号的岛
}
//b[k]=0;
}
if(sum>maxsum) maxsum=sum;
}
}
}
}
if(maxsum==0) maxsum=X*Y;//没有海的情况下
return maxsum;
}
};