代码随想录算法训练营第四十二天|广度优先搜索理论基础、岛屿数量:深搜版、岛屿数量:广搜版

广度优先搜索理论基础

广搜(bfs)是一圈一圈的搜索过程。因为广搜是从起点出发,以起始点为中心一圈一圈进行搜索,一旦遇到终点,记录之前走过的节点就是一条最短路。

广搜的过程:我们从图中可以看出,从start起点开始,是一圈一圈,向外搜索,方格编号1为第一步遍历的节点,方格编号2为第二步遍历的节点,第四步的时候我们找到终止点end。

正是因为BFS一圈一圈的遍历方式,所以一旦遇到终止点,那么一定是一条最短路径。

代码框架:

其实,我们仅仅需要一个容器,能保存我们要遍历过的元素就可以,那么用队列,还是用栈,甚至用数组,都是可以的

用队列的话,就是保证每一圈都是一个方向去转,例如统一顺时针或者逆时针

因为队列是先进先出,加入元素和弹出元素的顺序是没有改变的。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

int dir[4][2] = {0, 1, 1, 0, -1, 0, 0, -1};
void bfs(vector<vector<int>>& grid, vector<vector<bool>>& visited, int x, int y){
    queue<pair<int, int>> que;
    que.push({})//起始节点加入队列
    visited[x][y] = true;
    while(!que.empty()){
        pair<int, int> cur = que.front();
        que.pop();
        int curx = cur.first();
        int cury = cur.second();
        for(int i=0; i<4; i++){
            int nextx = curx + dir[i][0];
            int nexty = cury + dir[i][1];
            if(nextx<0||nextx>=grid.size()||nexty<0||nexty>=grid[0].size()) continue;
            if(!visited[nextx][nexty]){ // 如果节点没被访问过
                que.push({nextx, nexty}); // 队列添加该节点为下一轮要遍历的节点
                visited[nextx][nexty] = true; // 只要加入队列立刻标记,避免重复访问
            }
        }
    }

}

99. 岛屿数量:深搜版

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

//N和M表示矩阵的行数和列数
int dir[4][2] = {0,1,1,0,-1,0,0,-1};
void dfs(const vector<vector<int>>& grid, vector<vector<bool>>& visited, int x, int y){
    for(int i=0; i<4; i++){
        int nextx = x + dir[i][0];
        int nexty = y + dir[i][1];
        if(nextx<0||nextx>=grid.size()||nexty<0||nexty>=grid[0].size()) continue;
        if(!visited[nextx][nexty] && grid[nextx][nexty] == 1){
            visited[nextx][nexty] = true;
            dfs(grid, visited, nextx, nexty);
        }
    }
}

int main(){
    int n, m;
    cin>>n>>m;
    vector<vector<int>> grid(n, vector<int>(m, 0));
    for(int i=0; i<n; i++){
        for(int j=0; j<m; j++){
            cin>>grid[i][j];
        }
    }
    vector<vector<bool>> visited(n, vector<bool>(m, false));
    int result = 0;
    for(int i=0; i<n; i++){
        for(int j=0; j<m; j++){
            if(!visited[i][j]&&grid[i][j]==1){
                visited[i][j] = true;
                result++;
                dfs(grid, visited, i, j);
            }
        }
    }
    cout<<result<<endl;
}

99. 岛屿数量:广搜版

只要 加入队列就代表 走过,就需要标记,而不是从队列拿出来的时候再去标记走过

如果从队列拿出节点,再去标记这个节点走过,就会发生下图所示的结果,会导致很多节点重复加入队列。

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

int dir[4][2] = {0,1,1,0,-1,0,0,-1};
void bfs(const vector<vector<int>>& grid, vector<vector<bool>>& visited, int x, int y){
    queue<pair<int, int>> que;
    que.push({x, y});
    visited[x][y] = true;
    while(!que.empty()){
        pair<int, int> cur = que.front();
        que.pop();
        int curx = cur.first;
        int cury = cur.second;
        for(int i=0; i<4; i++){
            int nextx = curx + dir[i][0];
            int nexty = cury + dir[i][1];
            if(nextx<0||nextx>=grid.size()||nexty<0||nexty>=grid[0].size()) continue;
            if(!visited[nextx][nexty] && grid[nextx][nexty]==1){
                que.push({nextx, nexty});
                visited[nextx][nexty] = true;//只要访问就要标记
            }
        }
    }
}
int main(){
    int n, m;
    cin>>n>>m;
    vector<vector<int>> grid(n, vector<int>(m, 0));
    for(int i=0; i<n; i++){
        for(int j=0; j<m; j++){
            cin>>grid[i][j];
        }
    }
    vector<vector<bool>> visited(n, vector<bool>(m, false));
    int result = 0;
    for(int i=0; i<n; i++){
        for(int j=0; j<m; j++){
            if(!visited[i][j] && grid[i][j]==1){
                result++;
                bfs(grid, visited, i, j);
            }
        }
    }
    cout<<result<<endl;
}
相关推荐
core5122 小时前
PageRank 算法:互联网的“人气投票”
算法·pagerank
小白菜又菜2 小时前
Leetcode 1523. Count Odd Numbers in an Interval Range
算法·leetcode
你们补药再卷啦3 小时前
人工智能算法概览
人工智能·算法
cnxy1883 小时前
围棋对弈Python程序开发完整指南:步骤3 - 气(Liberties)的计算算法设计
python·算法·深度优先
AndrewHZ3 小时前
【图像处理基石】什么是光栅化?
图像处理·人工智能·算法·计算机视觉·3d·图形渲染·光栅化
小白菜又菜3 小时前
Leetcode 944. Delete Columns to Make Sorted
算法·leetcode
我找到地球的支点啦4 小时前
Matlab系列(006) 一利用matlab保存txt文件和读取txt文件
开发语言·算法·matlab
Dev7z4 小时前
基于Matlab实现GRACE卫星重力数据的全球水储量变化估算与分析
人工智能·算法·matlab
爱喝热水的呀哈喽4 小时前
11题目汇总
算法
三斗米5 小时前
Transformer入门:一文读懂《Attention Is All You Need》
算法·架构