LeetCode 827.最大人工岛 Making A Large Island

题目链接

二维数组里,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;
    }
};

猜你喜欢

转载自blog.csdn.net/ZRXSLYG/article/details/80462492