int[][] dirs={{0,1},{1,0},{0,-1},{-1,0}};//四个方向
int[][] g;
int n;
Deque<int[]> edge;//边界
public int shortestBridge(int[][] grid) {
g=grid;
n=grid.length;
edge=new ArrayDeque<>();
out:for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(g[i][j]==1){
BFS(i,j);//找到第一个岛屿,标记并寻找边界
break out;
}
}
}
//从边界开始一层层扩展,直到遇到另外的岛屿
int layer=0;
while (!edge.isEmpty()){
int size=edge.size();//当前层数量
for (int i = 0; i < size; i++) {
int[] cur=edge.poll();//从先进入的开始遍历
//下一层入队
for (int[] dir : dirs) {
int nr=cur[0]+dir[0],nc=cur[1]+dir[1];
if(nr>=0&&nr<n&&nc>=0&&nc<n&&g[nr][nc]!=-1){
if(g[nr][nc]==1) return layer;//遇到
edge.offer(new int[]{nr,nc});
g[nr][nc]=-1;
}
}
}
layer++;//扩展一层后层数+1
}
return -1;
}
void BFS(int r,int c){
Deque<int[]> q=new ArrayDeque<>();
q.offer(new int[]{r,c});//起点入队
g[r][c]=-1;
while (!q.isEmpty()){
boolean find=false;
int[] cur=q.poll();//从先进入的开始遍历
//后面节点入队
for (int[] dir : dirs) {
int nr=cur[0]+dir[0],nc=cur[1]+dir[1];
if(nr>=0&&nr<n&&nc>=0&&nc<n&&g[nr][nc]!=-1){
if(g[nr][nc]==0){//判断是否为边界
find=true;
continue;
}
q.offer(new int[]{nr,nc});
g[nr][nc]=-1;//入队进行标记,防止重复添加
}
}
if(find) edge.add(new int[]{cur[0],cur[1]});
}
}
广度优先搜索算法leetcode.934
最新推荐文章于 2024-05-23 00:22:50 发布