【题目描述】
给你一个大小为 n x n
二进制矩阵 grid
。最多 只能将一格 0
变成 1
。
返回执行此操作后,grid
中最大的岛屿面积是多少?
岛屿 由一组上、下、左、右四个方向相连的 1
形成。
示例 1:
输入: grid = [[1, 0], [0, 1]] 输出: 3 解释: 将一格0变成1,最终连通两个小岛得到面积为 3 的岛屿。
首先,这个题对我来说真的很恶心,因为是刚刚刷图论的题目,一下子感觉上难度了,做了正正一个下午。现在说说思路。
思路:
一开始我的想法是用回溯法,遍历所有岛屿,然后把0改成1后用dfs求出相邻的岛屿的面积,最后取最大,提交的时候不出意外的超时了,很惨。。。
然后看了题解的思路,是先求出每个岛的面积,组成岛的每个块打上的标记,每个岛标记不一样,并且存在map里面
之后遍历地图,在为0的地方把上下左右的岛的面积加起来就可以了。但是里面有很多细节需要注意,特别是代码量一大,调试起来非常费劲,这个题目建议一定要二刷三刷
int ans = 0;
class Solution {
private:
int s=0;
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};
void dfs(vector<vector<int>>& grid, vector<vector<bool>>& visit, int x, int y, int mark) {
if (visit[x][y] || grid[x][y] == 0)
return;
s++;
visit[x][y] = true;
grid[x][y] = mark; // 标记岛屿
for (int i = 0; i < 4; i++) {
int fx = x + dx[i];
int fy = y + dy[i];
if (fx < 0 || fy < 0 || fx >= grid.size() || fy >= grid[0].size())
continue;
dfs(grid, visit, fx, fy, mark);
}
}
public:
int largestIsland(vector<vector<int>>& grid) {
int mark = 2;
int n = grid.size();
int m = grid[0].size();
bool isAllGrid = true;
unordered_map<int, int> ma;
vector<vector<bool>> visit =vector<vector<bool>>(n, vector<bool>(m, false));
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grid[i][j] == 0)
isAllGrid = false;
if (grid[i][j] == 1 && !visit[i][j]) {
s = 0;
dfs(grid, visit, i, j, mark);
ma[mark++] = s;
}
}
}
if (isAllGrid)
return n * m;
int Max=0;
unordered_set<int> visitedGrid;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
s = 1;
visitedGrid.clear();
if (grid[i][j] == 0) {
for (int k = 0; k < 4; k++) {
int fx = i + dx[k];
int fy = j + dy[k];
if (fx < 0 || fy < 0 || fx >= grid.size() || fy >= grid[0].size())
continue;
if (visitedGrid.count(grid[fx][fy]))
continue;
s += ma[grid[fx][fy]];
visitedGrid.insert(grid[fx][fy]);
}
}
Max = max(s, Max);
}
}
return Max;
}
};