最短的桥(BFS)
https://leetcode.cn/problems/shortest-bridge/description/
给你一个大小为\(n \times n\)的二元矩阵\(grid\),其中\(1\)表示陆地,\(0\)表示水域。
岛是由四面相连的 1 形成的一个最大组,即不会与非组内的任何其他 1 相连。grid 中 恰好存在两座岛 。
你可以将任意数量的\(0\)变为\(1\),以使两座岛连接起来,变成 一座岛 。
返回必须翻转的 0 的最小数目。
示例 1:
输入:grid = [[0,1],[1,0]]
输出:1
示例 2:
输入:grid = [[0,1,0],[0,0,0],[0,0,1]]
输出:2
示例 3:
输入:grid = [[1,1,1,1,1],[1,0,0,0,1],[1,0,1,0,1],[1,0,0,0,1],[1,1,1,1,1]]
输出:1
提示:
n == grid.length == grid[i].length
2 <= n <= 100
grid[i][j] 为 0 或 1
grid 中恰有两个岛
这个题就是典型的BFS,首先我们先找到一个小岛,然后我们对于这个小岛进行BFS,一步一步向外扩张,比如说step=2的时候我们将step=2全部踢出,然后将step=3进行遍历
class Solution {
public:
int dx[4]={0,0,-1,1};
int dy[4]={-1,1,0,0};
int n,m;
queue<pair<int,int>> points;
void dfs(vector<vector<int>>& grid,int x,int y){
grid[x][y]=-1;
queue<pair<int,int>>q;
q.push({x,y});
points.push({x,y});
while(!q.empty()){
auto tmp=q.front();
q.pop();
for(int i=0;i<4;i++){
int xx=tmp.first+dx[i];
int yy=tmp.second+dy[i];
if(xx>=0&&xx<n&&yy>=0&&yy<m&&grid[xx][yy]==1){
grid[xx][yy]=-1;
q.push({xx,yy});
points.push({xx,yy});
}
}
}
}
int shortestBridge(vector<vector<int>>& grid) {
n=grid.size(),m=grid[0].size();
queue<pair<int,int>> q;
int isfind=false;
// 找到第一个岛屿
for(int i=0;i<n;i++){
if(isfind) break;
for(int j=0;j<m;j++){
if(isfind) break;
if(grid[i][j]==1){
dfs(grid,i,j);
isfind=true;
break;
}
}
}
// 找另一个岛屿 BFS
int ans=0;
while(!points.empty()){
int size=points.size();//对于每一个轮向外扩充,比如说step=2的时候我们将step=2全部踢出,然后将step=3进行遍历
while(size--){
auto [x,y]=points.front();
points.pop();
for(int i=0;i<4;i++){
int xx=x+dx[i];
int yy=y+dy[i];
if(xx>=0&&xx<n&&yy>=0&&yy<m&&(grid[xx][yy]==0||grid[xx][yy]==1)){
if(grid[xx][yy]==1) return ans;
points.push({xx,yy});
grid[xx][yy]=-1;
}
}
}
ans++;
}
return ans;
}
};