827. Making A Large Island

问题:

给定m*n的二维数组,由0和1构成。

1代表陆地,0代表海洋。

求在任意一个0的位置填上陆地 1,使得获得最大面积陆地,求这个陆地的面积。

Example 1:
Input: grid = [[1,0],[0,1]]
Output: 3
Explanation: Change one 0 to 1 and connect two 1s, then we get an island with area = 3.

Example 2:
Input: grid = [[1,1],[1,0]]
Output: 4
Explanation: Change the 0 to 1 and make the island bigger, only one island with area = 4.

Example 3:
Input: grid = [[1,1],[1,1]]
Output: 4
Explanation: Can't change any 0 to 1, only one island with area = 4.
 
Constraints:
n == grid.length
n == grid[i].length
1 <= n <= 500
grid[i][j] is either 0 or 1.

  

解法:DFS

leetcode说明

思想:

首先对该地图,进行陆地标记color

标记记号从2开始...

(为了区分已经存在的0和1)

只有该陆地为 1 的时候,才可以标记。

标记时,向四周扩展,直到遇到海洋。同时记录该陆地的面积。作为返回值。

⚠️ 注意:若该陆地为 0 (海洋),返回0。若该陆地超出边缘,也返回 0。

 1     int getclr(int i, int j, vector<vector<int>>& grid) {
 2         if(i<0 || j<0 || i>=n || j>=m) return 0;
 3         else return grid[i][j];
 4     }
 5     // mark color
 6     // && return the size of this island
 7     int markclr(int i, int j, int clr, vector<vector<int>>& grid) {
 8         //we can only mark the cell whose color is 1. 
 9         if(getclr(i,j,grid)!=1) return 0;
10         grid[i][j] = clr;
11         //color the adjcent cell of (i,j)
12         return 1+markclr(i+1,j,clr,grid)+markclr(i,j+1,clr,grid)+
13             markclr(i-1,j,clr,grid)+markclr(i,j-1,clr,grid);
14     }

 

标记结束后,尝试所有0的cell,

若0填上陆地后,得到由该点连接的各个陆地面积之和。

⚠️ 注意:由于0以外的陆地都是1,因此所有陆地的面积都可计算到。0和1一定相邻。

对于一个0cell,

四周被标记了多少个大陆,就有多少个color,使用set保存这些color,会滤掉重复的color(同一块大陆)

将不同color的大陆面积相加+自己 1=即为该cell连起来大陆的面积。

 

 1         for(int i=0; i<n; i++) {
 2             for(int j=0; j<m ; j++) {
 3                 if(grid[i][j]==0) {
 4                     //get adjcent island color of this cell.
 5                     //and get each size of color to Add.
 6                     unordered_set<int> adjclr = {getclr(i+1,j,grid), 
 7                                                   getclr(i,j+1,grid), 
 8                                                   getclr(i-1,j,grid), 
 9                                                   getclr(i,j-1,grid)};
10                     //print_set(adjclr);
11                     res = max(res, 1+accumulate(adjclr.begin(), adjclr.end(), 0,
12                                               [&](int a, int b){return a+sizes[b];}));
13                 }
14             }
15         }

 

然后在所有0cell的计算结果中,选最大。

⚠️ 注意:当地图中全部为1,就有可能没有0cell。这时最大面积即为整个地图面积。

 

代码参考:

 1 class Solution {
 2 public:
 3    // void print_set(unordered_set<int>& seta){
 4    //     printf("{");
 5    //     for(int i:seta) {
 6    //         printf("%d,", i);
 7    //     }
 8    //     printf("}\n");
 9    // }
10     
11     int n,m;
12     //get color of cell(i,j), if (i,j)is invalid, return 0
13     //cause sizes's idx is from 0. there is no -1.
14     int getclr(int i, int j, vector<vector<int>>& grid) {
15         if(i<0 || j<0 || i>=n || j>=m) return 0;
16         else return grid[i][j];
17     }
18     // mark color
19     // && return the size of this island
20     int markclr(int i, int j, int clr, vector<vector<int>>& grid) {
21         //we can only mark the cell whose color is 1. 
22         if(getclr(i,j,grid)!=1) return 0;
23         grid[i][j] = clr;
24         //color the adjcent cell of (i,j)
25         return 1+markclr(i+1,j,clr,grid)+markclr(i,j+1,clr,grid)+
26             markclr(i-1,j,clr,grid)+markclr(i,j-1,clr,grid);
27     }
28     //create a map(sizes) to save the size of each color island.
29     int largestIsland(vector<vector<int>>& grid) {
30         //color to mark the island from 2.(cause to distinguish from existed 0 and 1)
31         vector<int> sizes={0,0};//sizes[color]=size; from 2.
32         
33         //initial every island with marking colors
34         n = grid.size();
35         m = grid[0].size();
36         for(int i=0; i<n; i++) {
37             for(int j=0; j<m ; j++) {
38                 if(grid[i][j]==1) {
39                     //mark color to the island including cell(i,j)
40                     //and add this size of this island with color(sizes.size())
41                     sizes.push_back(markclr(i, j, sizes.size(), grid));
42                     //printf("sizes.back():%d\n",sizes.back());
43                 }
44             }
45         }
46         
47         //check every 0 cell
48         int res=0;
49         for(int i=0; i<n; i++) {
50             for(int j=0; j<m ; j++) {
51                 if(grid[i][j]==0) {
52                     //get adjcent island color of this cell.
53                     //and get each size of color to Add.
54                     unordered_set<int> adjclr = {getclr(i+1,j,grid), 
55                                                   getclr(i,j+1,grid), 
56                                                   getclr(i-1,j,grid), 
57                                                   getclr(i,j-1,grid)};
58                     //print_set(adjclr);
59                     res = max(res, 1+accumulate(adjclr.begin(), adjclr.end(), 0,
60                                               [&](int a, int b){return a+sizes[b];}));
61                 }
62             }
63         }
64         if(res==0) return m*n;//all cell is 1
65         else return res;
66     }
67 };

 

posted @ 2021-03-07 13:22  habibah_chang  阅读(67)  评论(0编辑  收藏  举报