一、Description
题目描述:给定一个二维数组,所有值为1的相邻元素(上下左右相邻)构成一个岛,即相互连通。在给出的数组中存在两个岛,求使得这两个岛连通需要最少将多少个数字0变为1。
二、Analyzation
首先通过深度优先搜索将一个岛的所有结点加入到一个队列中,并全部标记为已访问,然后依次从队列中取出Point,再次遍历(向上下左右四个方向探索),一旦遇到数字1,则返回此时的counts(因为是广搜,所以一定是最小的步数),如果遇到数字0,就入队。
三、Accepted code
class Solution {
int[][] dir = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int[][] vis;
int counts = 0;
Queue<Point> queue = new LinkedList<>();
public int shortestBridge(int[][] A) {
if (A == null) {
return 0;
}
int m = A.length;
int n = A[0].length;
vis = new int[m][n];
boolean flag = false;
for (int i = 0; i < m; i++) {
if (flag) {
break;
}
for (int j = 0; j < n; j++) {
if (A[i][j] == 1) {
vis[i][j] = 1;
dfs(A, i, j, m, n);
flag = true;
break;
}
}
}
while (!queue.isEmpty()) {
int size = queue.size();
while (size > 0) {
Point temp = queue.poll();
for (int i = 0; i < 4; i ++) {
int x = temp.x + dir[i][0];
int y = temp.y + dir[i][1];
if (x >= 0 && x < m && y >= 0 && y < n && vis[x][y] == 0) {
if (A[x][y] == 1) {
return counts;
}
vis[x][y] = 1;
queue.add(new Point(x, y));
}
}
size--;
}
counts++;
}
return -1;
}
public void dfs(int[][] A, int x, int y, int m, int n) {
queue.add(new Point(x, y));
for (int i = 0; i < 4; i++) {
int xx = x + dir[i][0];
int yy = y + dir[i][1];
if (xx >= 0 && xx < m && yy >= 0 && yy < n && vis[xx][yy] == 0 && A[xx][yy] == 1) {
vis[xx][yy] = 1;
dfs(A, xx, yy, m, n);
}
}
}
}
class Point {
int x = 0;
int y = 0;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}