力扣 每日一题 934. 最短的桥难度:中等,rating: 1825(dfs / bfs)
Posted nefu-ljw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了力扣 每日一题 934. 最短的桥难度:中等,rating: 1825(dfs / bfs)相关的知识,希望对你有一定的参考价值。
文章目录
题目链接
https://leetcode.cn/problems/shortest-bridge/
题目来源于: 第109场周赛 Q3 rating: 1825
思路一(两次dfs)
题目要求的实际上是两个由1组成的连通块之间的最小距离。
那么直接可以想到:把这两个连通块内的所有点分别求出来,然后O(n2)遍历这些点,求它们的最小距离即为答案。
两次dfs(深度优先搜索)即可得到两个连通块内的所有点。
代码一
class Solution
vector<pair<int,int> > g[2]; // 分别存2个连通块内的所有点的坐标
int dir[4][2]=0,1,0,-1,1,0,-1,0;
bool vis[110][110];
// 以(x,y)为起点,开始找值为1的连通块
void dfs(int x,int y,vector<vector<int>>& grid,vector<pair<int,int> >& ans)
int n=grid.size();
vis[x][y]=1;
ans.push_back(make_pair(x,y));
for(int i=0;i<4;i++)
int new_x=x+dir[i][0];
int new_y=y+dir[i][1];
if(new_x>=0&&new_x<n&&new_y>=0&&new_y<n&&grid[new_x][new_y]&&!vis[new_x][new_y])
dfs(new_x,new_y,grid,ans);
public:
int shortestBridge(vector<vector<int>>& grid)
memset(vis,0,sizeof(vis));
int n=grid.size();
int cnt=0; // 连通块的编号,cnt=0或1
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(grid[i][j]&&!vis[i][j])
// 题目条件“两个连通块”限制只会搜索两次
dfs(i,j,grid,g[cnt]);
cnt++;
int mi=0x3f3f3f3f;
for(int i=0;i<g[0].size();i++)
for(int j=0;j<g[1].size();j++)
auto [x1,y1]=g[0][i];
auto [x2,y2]=g[1][j];
int dis=abs(x1-x2)+abs(y1-y2)-1;
assert(dis>0);
mi=min(mi,dis);
return mi;
;
思路二(一次dfs + 一次bfs)
一次dfs把第一个连通块内的所有点(值为1)加入到队列中,然后开始一次bfs(广度优先搜索),每次扩展一层值为0的点,直到扩展到值为1的点,说明遇到了第二个连通块,结束bfs。bfs扩展的步数即为答案。
代码二
class Solution
struct node
int x,y,cnt;
;
queue<node> q; // 用于bfs的队列
int dir[4][2]=0,1,0,-1,1,0,-1,0;
bool vis[110][110];
// 以(x,y)为起点,开始找值为1的连通块
void dfs(int x,int y,vector<vector<int>>& grid)
int n=grid.size();
vis[x][y]=1;
q.push(x,y,0); // 第一个连通块的所有点加入队列,初始步数为0
for(int i=0;i<4;i++)
int new_x=x+dir[i][0];
int new_y=y+dir[i][1];
if(new_x>=0&&new_x<n&&new_y>=0&&new_y<n&&grid[new_x][new_y]&&!vis[new_x][new_y])
dfs(new_x,new_y,grid);
public:
int shortestBridge(vector<vector<int>>& grid)
memset(vis,0,sizeof(vis));
int n=grid.size();
bool flag=0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(grid[i][j])
// 由flag限制只找一个连通块
dfs(i,j,grid);
flag=1; // 找到一个连通块了
break; // 结束第二层循环
if(flag)
break; // 结束第一层循环
while(!q.empty())
auto [x,y,cnt]=q.front();
q.pop();
for(int i=0;i<4;i++)
int new_x=x+dir[i][0];
int new_y=y+dir[i][1];
if(new_x>=0&&new_x<n&&new_y>=0&&new_y<n&&!vis[new_x][new_y])
vis[new_x][new_y]=1;
if(!grid[new_x][new_y])
q.push(new_x,new_y,cnt+1);
else if(grid[new_x][new_y])
return cnt;
return -1;
;
以上是关于力扣 每日一题 934. 最短的桥难度:中等,rating: 1825(dfs / bfs)的主要内容,如果未能解决你的问题,请参考以下文章
力扣 每日一题 870. 优势洗牌难度:中等(贪心+双指针)
力扣 每日一题 870. 优势洗牌难度:中等,rating: 1648(贪心+双指针)