# 0934. Shortest Bridge
###### tags: `Leetcode` `Medium` `FaceBook` `Microsoft` `DFS` `BFS`
Link: https://leetcode.com/problems/shortest-bridge/
## 思路
虽然想出来不难 但是不好写
之后可以再写一遍
**注意:遇到这种可以上下左右跑的题,可以单独写一个findneighbor function 来节省时间,另外在用比较复杂的数据结构 例如queue stack存点的时候可以存成i*columnNum+j来节省空间**
第二遍写的时候debug de了很久,就是因为在getComponents的时候是这样写的
```java=
while(!stack.isEmpty()){
int node = stack.pop();
int r = node/C;
int c = node%C;
colors[r][c] = t;
for(int nei:neighbors(grid, r, c)){
int nr = nei/C, nc = nei%C;
if(grid[nr][nc]==1 && colors[nr][nc]==0){
stack.push(nr*C+nc);
}
}
}
```
这样写的话一开始访问到一个没有被访问到的点会加进queue里面,之后再通过其他点访问到这个点还是会加进list,就导致了TLE
所以遇到这种**用visited检查的题,在找到邻居并判断出没有被visited之后,就改成visited**
## Code
```java=
class Solution {
Queue<Integer> q = new LinkedList<>();
Set<Integer> set = new HashSet<>();
boolean[][] visited;
public int shortestBridge(int[][] grid) {
int R = grid.length, C = grid[0].length;
int[][] colors = getComponents(grid);
for(int i = 0;i < colors.length;i++){
for(int j = 0;j < colors[0].length;j++){
if(colors[i][j]==1 && isEdge(grid,i,j)){
q.add(i*C+j);
}
if(colors[i][j]==2){
set.add(i*C+j);
}
}
}
int depth = 0;
while(!q.isEmpty()){
int size = q.size();
for(int i = 0;i < size;i++){
int node = q.poll();
if(set.contains(node)){
return depth-1;
}
for(int nei: neighbors(grid, node/C, node%C)){
int nr = nei/C, nc = nei%C;
if(colors[nr][nc]!=1){
q.add(nei);
colors[nr][nc]=1;
}
}
}
depth++;
}
return -1;
}
public int[][] getComponents(int[][] grid){
int R = grid.length, C = grid[0].length;
int[][] colors = new int[R][C];
int t = 0;
for(int i = 0;i < R;i++){
for(int j = 0;j < C;j++){
if(colors[i][j]==0 && grid[i][j]==1){
Stack<Integer> stack = new Stack();
stack.push(i*C+j);
colors[i][j] = ++t;
while(!stack.isEmpty()){
int node = stack.pop();
int r = node/C;
int c = node%C;
for(int nei:neighbors(grid, r, c)){
int nr = nei/C, nc = nei%C;
if(grid[nr][nc]==1 && colors[nr][nc]==0){
colors[nr][nc] = t;
stack.push(nr*C+nc);
}
}
}
}
}
}
return colors;
}
public List<Integer> neighbors(int[][] grid, int r, int c){
int R = grid.length;
int C = grid[0].length;
List<Integer> ans = new ArrayList();
if(r-1>=0) ans.add((r-1)*C+c);
if(c-1>=0) ans.add(r*C+c-1);
if(r+1<R) ans.add((r+1)*C+c);
if(c+1<C) ans.add(r*C+c+1);
return ans;
}
public boolean isEdge(int[][] grid, int x, int y){
int R = grid.length;
int C = grid[0].length;
for(int nei:neighbors(grid,x,y)){
if(grid[nei/C][nei%C]==0){
return true;
}
}
return false;
}
}
```