在给定的二维二进制数组 A 中,存在两座岛。(岛是由四面相连的 1 形成的一个最大组。)
现在,我们可以将 0 变为 1,以使两座岛连接起来,变成一座岛。
返回必须翻转的 0 的最小数目。(可以保证答案至少是 1。)
示例 1:
输入:[[0,1],[1,0]]
输出:1
示例 2:
输入:[[0,1,0],[0,0,0],[0,0,1]]
输出:2
示例 3:
输入:[[1,1,1,1,1],[1,0,0,0,1],[1,0,1,0,1],[1,0,0,0,1],[1,1,1,1,1]]
输出:1
提示:
1 <= A.length = A[0].length <= 100
A[i][j] == 0 或 A[i][j] == 1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/shortest-bridge
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解:
解法效率较低
1.用dfs找到两座桥并分别将其中的1,标为2和3
2.用bfs从全用2标注的桥,找与全是3标注的桥的最短距离
class Solution {
int[][] dis = {{0,1},{0,-1},{1,0},{-1,0}};
int[][] vis;
int m, n;
public int shortestBridge(int[][] A) {
m = A.length;
n = A[0].length;
int ans = m*n;
int count = 2;
//1.找到两座岛屿,使用dfs
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
if(A[i][j] == 1) {
A[i][j] = count;
dfs(i,j, A, count);
count++;
}
}
}
//2.使用bfs,找到两岛相连的最小距离
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
if(A[i][j] == 2) {
vis = new int[m][n];
ans = Math.min(ans, bfs(i, j, A));
}
}
}
return ans;
}
private int bfs(int x, int y, int[][] a) {
Queue queue = new LinkedList<>();
queue.add(new int[]{x,y});
int step = 0;
vis[x][y] = 1;
while (!queue.isEmpty()) {
int size = queue.size();
for (int i = 0; i < size; i++) {
int[] poll = queue.poll();
for (int k = 0; k < 4; k++) {
int nx = poll[0] + dis[k][0];
int ny = poll[1] + dis[k][1];
if(nx < m && nx >= 0 && ny < n && ny >= 0 && vis[nx][ny] == 0) {
if(a[nx][ny] == 3) {
return step == 0 ? 1 : step;
}
if(a[nx][ny] == 0) {
vis[nx][ny] = 1;
queue.add(new int[]{nx,ny});
}
}
}
}
step++;
}
return m*n;
}
private void dfs(int x, int y, int[][] a, int count) {
for(int i = 0; i < 4; i++) {
int nx = x + dis[i][0];
int ny = y + dis[i][1];
if(nx >= 0 && nx < m && ny >= 0 && ny < n && a[nx][ny] == 1) {
a[nx][ny] = count;
dfs(nx, ny, a, count);
}
}
}
}