class Solution {
private:
int m, n;
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
void dfs(vector<vector<int>>& grid, int i, int j, int id) {
if (i < 0 || i >= m || j < 0 || j >= n || grid[i][j] != 1) return;
grid[i][j] = id; // if grid[i][j] == 1
for (int k = 0; k < 4; k++) {
dfs(grid, i + dx[k], j + dy[k], id);
}
}
public:
int largestIsland(vector<vector<int>>& grid) {
m = grid.size(); n = grid[0].size();
int id = 2;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
dfs(grid, i, j, id++);
}
}
unordered_map<int, int> sizeMap;
int maxSize = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] > 1) {
maxSize = max(maxSize, ++sizeMap[grid[i][j]]);
}
}
}
vector<bool> visited(id, false);
int up, down, left, right, merge;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 0) {
up = (i > 0) ? grid[i - 1][j] : 0;
down = (i + 1 < m) ? grid[i + 1][j] : 0;
left = (j > 0) ? grid[i][j - 1] : 0;
right = (j + 1 < n) ? grid[i][j + 1] : 0;
visited[up] = true;
merge = 1 + sizeMap[up];
if (!visited[down]) {
merge += sizeMap[down]; visited[down] = true;
}
if (!visited[left]) {
merge += sizeMap[left]; visited[left] = true;
}
if (!visited[right]) {
merge += sizeMap[right]; visited[right] = true;
}
maxSize = max(maxSize, merge);
visited[up] = false;
visited[down] = false;
visited[left] = false;
visited[right] = false;
}
}
}
return maxSize;
}
};