1. 题目
1.1 题意
找出被1围住的0的区域的数量
1.2 分析
1 <= grid.length, grid[0].length <= 100
0 <= grid[i][j] <=1
这个题要搜索为0的区域,遍历每个位置,如果该位置为0,那么就由这个点开始做bfs广度优先搜索,然后访问过的0的位置需要打个标记已经访问,可以直接在数组原地打标记,让后不会在访问访问过的点。
在开始bfs前需要使用一个标记,来记录bfs过程是否遇到了边界,如果遇到了边界,就不是合法的情况。
1.3 我的解法
class Solution {
public:
int closedIsland(vector<vector<int>>& grid) {
int res=0;
int index = 1;
int n = grid.size(), m = grid[0].size();
// 四个方向
vector<int> x_bias{1,0,-1,0};
vector<int> y_bias{0,1,0,-1};
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
// 该位置是未遍历的陆地
if(grid[i][j] == 0){
index ++ ; // 用不同的下标标记不同的联通陆地区域
int changeFlag = 1; // 标记是否没有遇到边界
if(i == 0 || i == n-1 || j == 0 || j == m-1){
// 无效陆地区域
changeFlag = 0;
}
// bfs
queue<pair<int, int> > q;
q.push(make_pair(i,j) );
while(!q.empty()){
int x = q.front().first;
int y = q.front().second;
q.pop();
// 标记该块陆地已经访问过
grid[x][y] = index;
// 向四个方向搜索
for(int k=0;k<4;k++){
int dx = x + x_bias[k];
int dy = y + y_bias[k];
if(dx >=0 && dx < n && dy >= 0 && dy < m){
// 判断是否合法位置
if(grid[dx][dy] == 1){
// 搜到海洋直接结束
continue;
}
else if(grid[dx][dy] == 0){
// 搜到陆地继续搜索
q.push(make_pair(dx, dy) );
}
if(dx == 0 || dx == n-1 || dy == 0 || dy == m-1){
// 搜到边界
// 无效陆地区域
changeFlag = 0;
}
}
}
}
if(changeFlag){
// 如果没有靠到边界
// 为需要计算到的陆地区域数
res++;
}
}
}
}
return res;
}
};
1.4 学习题解反思
时间复杂度O(mn), 空间复杂度O(mn)(最坏情况需要记录所有的点)
题解中看到一个有意思的解法,先把边界的0通过搜索变成1,在进行bfs,这样可以不用使用标记来记录。
1.5 bug日记
居然调对了
2. 后记
仅分享自己的想法,有意见和指点非常感谢
文章介绍了LeetCode1254题目的解法,主要通过BFS广度优先搜索策略来找出并计数被1包围的0的区域。在遍历过程中,遇到0则开始搜索,并标记已访问,同时处理边界条件。时间复杂度为O(mn),空间复杂度也为O(mn)。作者分享了自己的代码实现,并提到一种优化思路,即先处理边界上的0。最后,作者表示代码一次性调试正确。
775

被折叠的 条评论
为什么被折叠?



