classSolution { int dx[4] = {0, 1, 0, -1}; int dy[4] = {1, 0, -1, 0}; public: voiddfs(int x, int y, vector<vector<int>>& grid, int n, int m){ grid[x][y] = 2; for (int i = 0; i < 4; ++i) { int tx = dx[i] + x; int ty = dy[i] + y; if (tx < 0 || tx >= n || ty < 0 || ty >= m || grid[tx][ty] != 1) { continue; } dfs(tx, ty, grid, n, m); } } intcount(vector<vector<int>>& grid, int n, int m){ int cnt = 0; for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { if (grid[i][j] == 1) { cnt++; dfs(i, j, grid, n, m); } } } // 还原 for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { if (grid[i][j] == 2) { grid[i][j] = 1; } } } return cnt; } intminDays(vector<vector<int>>& grid){ int n = grid.size(), m = grid[0].size(); // 岛屿数量不为 1,陆地已经分离 if (count(grid, n, m) != 1) { return0; } for (int i = 0; i < n; ++i) { for (int j = 0; j < m; ++j) { if (grid[i][j]) { grid[i][j] = 0; if (count(grid, n, m) != 1) { // 更改一个陆地单元为水单元后陆地分离 return1; } grid[i][j] = 1; } } } return2; } };
publicintminDays(int[][] grid) { intn= grid.length, m = grid[0].length; // 岛屿数量不为 1,陆地已经分离 if (count(grid, n, m) != 1) { return0; } for (inti=0; i < n; ++i) { for (intj=0; j < m; ++j) { if (grid[i][j] != 0) { grid[i][j] = 0; if (count(grid, n, m) != 1) { // 更改一个陆地单元为水单元后陆地分离 return1; } grid[i][j] = 1; } } } return2; }
publicintcount(int[][] grid, int n, int m) { intcnt=0; for (inti=0; i < n; ++i) { for (intj=0; j < m; ++j) { if (grid[i][j] == 1) { cnt++; dfs(i, j, grid, n, m); } } } // 还原 for (inti=0; i < n; ++i) { for (intj=0; j < m; ++j) { if (grid[i][j] == 2) { grid[i][j] = 1; } } } return cnt; }
publicvoiddfs(int x, int y, int[][] grid, int n, int m) { grid[x][y] = 2; for (inti=0; i < 4; ++i) { inttx= dx[i] + x; intty= dy[i] + y; if (tx < 0 || tx >= n || ty < 0 || ty >= m || grid[tx][ty] != 1) { continue; } dfs(tx, ty, grid, n, m); } } }
constdfs = (x, y, grid, n, m) => { grid[x][y] = 2; for (let i = 0; i < 4; ++i) { const tx = dx[i] + x; const ty = dy[i] + y; if (tx < 0 || tx >= n || ty < 0 || ty >= m || grid[tx][ty] != 1) { continue; } dfs(tx, ty, grid, n, m); } }
constcount = (grid, n, m) => { let cnt = 0; for (let i = 0; i < n; ++i) { for (let j = 0; j < m; ++j) { if (grid[i][j] == 1) { cnt++; dfs(i, j, grid, n, m); } } } // 还原 for (let i = 0; i < n; ++i) { for (let j = 0; j < m; ++j) { if (grid[i][j] == 2) { grid[i][j] = 1; } } } return cnt; } var minDays = function(grid) { const n = grid.length, m = grid[0].length; // 岛屿数量不为 1,陆地已经分离 if (count(grid, n, m) != 1) { return0; } for (let i = 0; i < n; ++i) { for (let j = 0; j < m; ++j) { if (grid[i][j]) { grid[i][j] = 0; if (count(grid, n, m) != 1) { // 更改一个陆地单元为水单元后陆地分离 return1; } grid[i][j] = 1; } } } return2; };
classSolution: defminDays(self, grid: List[List[int]]) -> int: defdfs(x: int, y: int): grid[x][y] = 2 for tx, ty in [(x, y + 1), (x + 1, y), (x, y - 1), (x - 1, y)]: if0 <= tx < n and0 <= ty < m and grid[tx][ty] == 1: dfs(tx, ty) defcount(): cnt = 0 for i inrange(n): for j inrange(m): if grid[i][j] == 1: cnt += 1 dfs(i, j) # 还原 for i inrange(n): for j inrange(m): if grid[i][j] == 2: grid[i][j] = 1 return cnt n, m = len(grid), len(grid[0]) # 岛屿数量不为 1,陆地已经分离 if count() != 1: return0 for i inrange(n): for j inrange(m): if grid[i][j]: grid[i][j] = 0 if count() != 1: # 更改一个陆地单元为水单元后陆地分离 return1 grid[i][j] = 1 return2
复杂度分析
时间复杂度:O(n^2m^2),其中 n 为网格高度,m 为网格宽度。时间复杂度瓶颈在于枚举更改一个陆地单元为水单元,统计当前有多少岛屿,这里每次枚举需要 O(nm) 的时间复杂度,统计当前有多少岛屿需要 O(nm) 的时间复杂度,因此总时间复杂度为 O(n^2m^2)。
public: intminDays(vector<vector<int>>& grid){ int m = grid.size(); int n = grid[0].size(); // 节点重标号 int landCount = 0; unordered_map<int, int> relabel; for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { if (grid[i][j] == 1) { relabel[i * n + j] = landCount; ++landCount; } } } if (!landCount) { return0; } if (landCount == 1) { return1; }
// 添加图中的边 vector<vector<int>> edges(landCount); for (int i = 0; i < m; ++i) { for (int j = 0; j < n; ++j) { if (grid[i][j] == 1) { for (int d = 0; d < 4; ++d) { int ni = i + dirs[d][0]; int nj = j + dirs[d][1]; if (ni >= 0 && ni < m && nj >= 0 && nj < n && grid[ni][nj] == 1) { edges[relabel[i * n + j]].push_back(relabel[ni * n + nj]); } } } } }
auto scc = TarjanSCC(edges); return scc.check(); } };