参考别人的做法,第一次碰到广度遍历/深度遍历的题目
class Solution {
public int shortestBridge(int[][] A) {
int R = A.length;
int C = A[0].length;
int[][] direction = new int[][]{{1,0},{-1,0},{0,1},{0,-1}};
// 定义双端队列
// 创建一个队列,保存的是访问到的格子坐标,是个二维数组
Deque<int []> queue = new ArrayDeque<>();
int ans = -1;
boolean[][] visited = new boolean[R][C];
boolean flag = true;
// 找到1个1进行深度遍历,就结束循环
for(int i=0;i<R && flag;i++){
for(int j = 0;j<C;j++){
if(A[i][j]==1){
dfs(A,i,j,queue,visited);
flag = false;
break;
}
}
}
// 当前队列不为空
while(!queue.isEmpty()){
// 队列的大小
int size = queue.size();
ans++;
for(int i =0;i<size;i++){
// 广度遍历,找到一个坐标发散
int[] node = queue.poll();
// 四个方向
for(int j =0;j<4;j++){
int nx = node[0]+ direction[j][0];
int ny = node[1]+ direction[j][1];
if(nx<0||nx>=R||ny<0||ny>=C||visited[nx][ny]) continue;
// 发散到第二座岛屿的1了,可以联通两座岛屿
if(A[nx][ny] == 1) return ans;
visited[nx][ny] = true;
queue.add(new int[]{nx,ny});
}
}
}
return ans;
}
private void dfs(int[][] A,int i,int j,Deque queue, boolean[][] visited){
int R = A.length;
int C = A[0].length;
// 边界条件
if(i<0 || i>=R || j<0 || j>=C || visited[i][j] || A[i][j]!=1) return;
//标注这个格子被访问过
visited[i][j] = true;
// add方法表示把坐标点(i,j)加入到队列的队尾
queue.add(new int[]{i,j});
dfs( A, i-1, j, queue, visited);
dfs( A, i+1, j, queue, visited);
dfs( A, i, j-1, queue, visited);
dfs( A, i, j+1, queue, visited);
}
}