目录
1.每日一句
能治愈生活的良方,是保持对生活的热爱
2.作者简介
🏡个人主页:XiaoXiaoChen-2716
📚学习专栏:力扣专栏
🕒发布日期:2022/10/25
『LeetCode|每日一题』最短的桥
1.每日一题
2.解题思路
2.1 思路分析
刚开始想用两次深度优先分别找第一座岛屿和来搭桥,但是发现会超时,于是采用了DFS+BFS分别来找到一座岛屿和搜索另一座岛屿的任意位置
S1:首先写一个函数dfs用来找第一座岛屿,需要的参数有grid(矩阵)、方向参数i、j、还需要用一个队列来存这个岛屿的每一个'1',且队列存储的数据类型是一个数组记录位置;
S2:首先dfs不能越界,且当当前位置是水域(即数值为0时),退出循环;
S3:每找到一个1先把它存到队列中去,然后要区分它和另一个岛屿,所以这里我把第一个找的岛屿都变成了2;
S4:接下来用一个双层for循环开始BFS,首先定义一个ans来记录需要改变几个0,从队列里面取一个位置,从它开始向外扩展搜索(需要dx、dy两个方向数组,当然也可以用一个二维数组),BFS每次搜索到的0(水域)先放到队列中去(扩展的时候同样不能越界),然后都用-2来标记,扩散的圈数就是最短距离;
S5:如果是搜索到了1,那么说明已经找到另一座岛屿了,此时返回ans即可;
2.2 核心代码(DFS + BFS)
DFS:
//DFS 找第一座岛屿
private void dfs(int[][] grid , int i , int j , Queue<int[]> queue){
int n = grid.length;
if(i < 0 || i >= n || j < 0 || j >= n || grid[i][j] != 1){
return ;
}
queue.offer(new int[]{i , j});
grid[i][j] = 2;
dfs(grid , i + 1 , j , queue);
dfs(grid , i - 1 , j , queue);
dfs(grid , i , j + 1 , queue);
dfs(grid , i , j - 1 , queue);
}
BFS:
//BFS 搭桥
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < n ; j++){
if(grid[i][j] == 1){
dfs(grid , i , j , queue);
int ans = 0;
while(!queue.isEmpty()){
int len = queue.size();
for(int p = 0 ; p < len ; p++){
int[] flag = queue.poll();
int x = flag[0];
int y = flag[1];
for(int ii = 0 ; ii < 4 ; ii++){
int now_x = x + dx[ii];
int now_y = y + dy[ii];
if(now_x >= 0 && now_y >= 0 && now_x < n && now_y < n){
if(grid[now_x][now_y] == 0){
queue.offer(new int[]{now_x , now_y});
grid[now_x][now_y] = -2;
}else if(grid[now_x][now_y] == 1){
return ans;
}
}
}
}
ans++;
}
}
}
2.3 完整代码
class Solution {
public int shortestBridge(int[][] grid) {
int[] dx = {-1 , 0 , 0 , 1};
int[] dy = {0 , 1 , -1 , 0};
int n = grid.length;
Queue<int[]> queue = new ArrayDeque<>();
//BFS
for(int i = 0 ; i < n ; i++){
for(int j = 0 ; j < n ; j++){
if(grid[i][j] == 1){
dfs(grid , i , j , queue);
int ans = 0;
while(!queue.isEmpty()){
int len = queue.size();
for(int p = 0 ; p < len ; p++){
int[] flag = queue.poll();
int x = flag[0];
int y = flag[1];
for(int ii = 0 ; ii < 4 ; ii++){
int now_x = x + dx[ii];
int now_y = y + dy[ii];
if(now_x >= 0 && now_y >= 0 && now_x < n && now_y < n){
if(grid[now_x][now_y] == 0){
queue.offer(new int[]{now_x , now_y});
grid[now_x][now_y] = -2;
}else if(grid[now_x][now_y] == 1){
return ans;
}
}
}
}
ans++;
}
}
}
}
return 0;
}
//DFS 找第一座岛屿
private void dfs(int[][] grid , int i , int j , Queue<int[]> queue){
int n = grid.length;
if(i < 0 || i >= n || j < 0 || j >= n || grid[i][j] != 1){
return ;
}
queue.offer(new int[]{i , j});
grid[i][j] = 2;
dfs(grid , i + 1 , j , queue);
dfs(grid , i - 1 , j , queue);
dfs(grid , i , j + 1 , queue);
dfs(grid , i , j - 1 , queue);
}
}
2.4 运行结果
🍁 类似题目推荐:
如果文章对各位大佬有帮助就支持一下噢,右手受伤了导致操作困难,不好的地方请各位大佬多多指教!