使陆地分离的最少天数
难度:
标签:
题目描述
给你一个大小为 m x n
,由若干 0
和 1
组成的二维网格 grid
,其中 1
表示陆地, 0
表示水。岛屿 由水平方向或竖直方向上相邻的 1
(陆地)连接形成。
如果 恰好只有一座岛屿 ,则认为陆地是 连通的 ;否则,陆地就是 分离的 。
一天内,可以将 任何单个 陆地单元(1
)更改为水单元(0
)。
返回使陆地分离的最少天数。
示例 1:

输入:grid = [[0,1,1,0],[0,1,1,0],[0,0,0,0]] 输出:2 解释:至少需要 2 天才能得到分离的陆地。 将陆地 grid[1][1] 和 grid[0][2] 更改为水,得到两个分离的岛屿。
示例 2:

输入:grid = [[1,1]] 输出:2 解释:如果网格中都是水,也认为是分离的 ([[1,1]] -> [[0,0]]),0 岛屿。
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 30
grid[i][j]
为0
或1
代码结果
运行时间: 43 ms, 内存: 17.2 MB
/*
题目思路:
Java Stream 不适合处理深度优先搜索(DFS)和复杂的矩阵操作。因此,在这个问题中,我们需要使用常规的Java来处理DFS和网格操作。
由于问题的复杂性和DFS的需求,我们使用Java常规代码来实现,而不使用Java Stream。
*/
public class Solution {
private int[][] directions = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
public int minDays(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
if (countIslands(grid) != 1) return 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 1) {
grid[i][j] = 0;
if (countIslands(grid) != 1) return 1;
grid[i][j] = 1;
}
}
}
return 2;
}
private int countIslands(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
boolean[][] visited = new boolean[m][n];
int islands = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == 1 && !visited[i][j]) {
dfs(grid, visited, i, j);
islands++;
}
}
}
return islands;
}
private void dfs(int[][] grid, boolean[][] visited, int x, int y) {
int m = grid.length;
int n = grid[0].length;
if (x < 0 || y < 0 || x >= m || y >= n || grid[x][y] == 0 || visited[x][y]) return;
visited[x][y] = true;
for (int[] dir : directions) {
dfs(grid, visited, x + dir[0], y + dir[1]);
}
}
}
解释
方法:
这个题解的思路分为两个步骤:
1. 使用并查集判断初始时有多少个连通分量。如果连通分量数为0或大于2,那么答案为0,不需要改变任何陆地。
2. 如果只有一个连通分量,则使用Tarjan算法求割点。如果存在割点,则只需要删除一个割点就可以将图分成两部分,答案为1;否则需要删除两个点,答案为2。特殊情况是当全部都是陆地时,需要返回min(2, m*n)。
时间复杂度:
O(m*n)
空间复杂度:
O(m*n)
代码细节讲解
🦆
在题解中提到如果连通分量数为0或大于2则答案为0,但是如果所有单元都是陆地(即没有水单元),连通分量数为1,此时的答案应该是多少?
▷🦆
题解中使用并查集来找出连通分量,对于边界情况(比如只有一列或一行),并查集的处理方式是否有所不同?
▷🦆
在使用Tarjan算法求割点时,如何处理图中孤立的节点,即那些没有任何连接的单独陆地单元?
▷🦆
在并查集的实现中,路径压缩的具体作用是什么?如何通过路径压缩提高并查集的效率?
▷