DFS和BFS

23 篇文章 0 订阅

DFS

代码DFS

class Solution_Number_DFS {//岛屿数量
private:
    // 上下左右四个方向的数组
    vector<pair<int, int>> DIRECTIONS = { {0, 1}, {1, 0}, {0, -1}, {-1, 0} };

    // 构建DFS函数
    void DFS(vector<vector<string>>& grid, int i, int j, vector<vector<bool>>& checkList) {
        // 将该点标记为已经检查过
        checkList[i][j] = true;

        // 遍历上下左右四个方向的邻点坐标
        for (auto& dir : DIRECTIONS) {
            int next_i = i + dir.first;
            int next_j = j + dir.second;

            // 若近邻点满足三个条件:
            // 1.没有越界    2. 近邻点尚未被检查过   3.近邻点也为陆地
            if (next_i >= 0 && next_i < grid.size() && next_j >= 0 && next_j < grid[0].size()
                && !checkList[next_i][next_j] && grid[next_i][next_j] == "1") {
                // 对近邻点进行DFS搜索
                DFS(grid, next_i, next_j, checkList);
            }
        }
    }

public:
    int numIslands(vector<vector<string>>& grid) {
        int x = grid.size();    // 获得网格长
        int y = grid[0].size(); // 获得网格宽
        int ans = 0;            // 初始化答案为0

        // 初始化数组checkList用于DFS遍历过程中的检查
        // false表示尚未访问,true表示已经访问
        vector<vector<bool>> checkList(x, vector<bool>(y, false));

        // 对整个grid二维数组进行双重循环遍历
        for (int i = 0; i < x; i++) {
            for (int j = 0; j < y; j++) {
                // 若该点为陆地且还没有进行过搜寻
                if (grid[i][j] == "1" && !checkList[i][j]) {
                    // 可以进行DFS
                    DFS(grid, i, j, checkList);
                    // 做完DFS,连通块数量+1,更新答案
                    ans++;
                }
            }
        }
        return ans;
    }
};

BFS

代码BFS

class Solution_Number_BFS {
private:
    // 上下左右四个方向的数组
    vector<pair<int, int>> DIRECTIONS = { {0,1}, {1,0}, {0,-1}, {-1,0} };

public:
    int numIslands(vector<vector<char>>& grid) {
        int xLen = grid.size();    // 获得网格长
        int yLen = grid[0].size(); // 获得网格宽
        int ans = 0;               // 初始化陆地数目为0

        // 初始化和grid一样大小的二维数组checkList用于BFS遍历过程中的检查
        vector<vector<int>> checkList(xLen, vector<int>(yLen, 0));

        // 双重遍历grid数组
        for (int i = 0; i < xLen; i++) {
            for (int j = 0; j < yLen; j++) {
                // 若该点为陆地且还没有进行过搜寻
                // 找到了一个BFS搜索的起始位置(i,j)
                if (grid[i][j] == '1' && checkList[i][j] == 0) {
                    // 对于该片连通块,构建一个队列,初始化包含该点
                    queue<pair<int, int>> q;
                    q.push({ i, j });
                    // 修改checkList[i][j]为1,表示该点已经搜寻过
                    checkList[i][j] = 1;

                    // 进行BFS,退出循环的条件是队列为空
                    while (!q.empty()) {
                        // 弹出队头的点(x,y),搜寻该点上下左右的近邻点
                        int x = q.front().first;
                        int y = q.front().second;
                        q.pop();

                        // 遍历(x,y)上下左右的四个方向的近邻点
                        for (auto& dir : DIRECTIONS) {
                            int xNext = x + dir.first;
                            int yNext = y + dir.second;

                            // 如果近邻点满足三个条件
                            if (xNext >= 0 && xNext < xLen && yNext >= 0 && yNext < yLen
                                && checkList[xNext][yNext] == 0 && grid[xNext][yNext] == '1') {
                                // 对近邻点做两件事:
                                // 1. 入队       2. 标记为已检查过
                                q.push({ xNext, yNext });
                                checkList[xNext][yNext] = 1;
                            }
                        }
                    }
                    // 连通块的数量+1
                    ans++;
                }
            }
        }
        return ans;
    }
};

比较

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值