图论做题笔记:dfs

Leetcode - 797:所有可能的路径

题目:

给你一个有 n 个节点的 有向无环图(DAG) ,请你找出所有从节点 0 到节点 n-1 的路径并输出(不要求按特定顺序

graph[i] 是一个从节点 i 可以访问的所有节点的列表(即从节点 i 到节点 graph[i][j]存在一条有向边)。

示例 1:

复制代码
输入:graph = [[1,2],[3],[3],[]]
输出:[[0,1,3],[0,2,3]]
解释:有两条路径 0 -> 1 -> 3 和 0 -> 2 -> 3

示例 2:

复制代码
输入:graph = [[4,3,1],[3,2,4],[3],[4],[]]
输出:[[0,4],[0,3,4],[0,1,3,4],[0,1,2,3,4],[0,1,4]]

笔记:

dfs就是递归加回溯所以和我们的递归三部曲差不多也有深搜三部曲:

1.确定参数:我们传入的参数有graph和当前节点的下标x

2.确定终止条件:如果我们遍历到了租后一个节点就返回

3.处理目前搜索节点出发的路径:

遍历graph的每个节点,将各个节点所连接的节点依次加入到path数组中,接着进行递归处理,在递归完成之后记得要回溯,将加入的节点弹出。

cpp 复制代码
class Solution {
public:
    vector<int> path;
    vector<vector<int>> res;
    void dfs(vector<vector<int>>& graph, int x){
        if(x == graph.size() - 1){
            res.push_back(path);
            return;
        }
        for(int i = 0; i < graph[x].size(); i++){
            path.push_back(graph[x][i]);
            dfs(graph, graph[x][i]);
            path.pop_back();
        }
    }
    vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {
        path.push_back(0);
        dfs(graph, 0);
        return res;
    }
};

Leetcode - 200:岛屿数量

题目:

笔记:

这道题跟上道题又不一样了,因为我们这道题并没有在递归处理之后进行回溯处理。那为什么这道题不用回溯而上一道题需要回溯呢?因为上一道题就像是链表的结构,一个点可以连接多个点,我们可以想象成树的结构来做,我们在遍历树寻找节点的时候在深搜的同时必须伴随着回溯使得我们不会落下任意一个路径,二这道题不一样的点在于给了我们一个二维的空间图,在寻找特定点时我们只管往前走不需要考虑有便利不到的情况因为next(x,y)会将四个方向的点都处理一遍。所以我们只需要考虑深搜三部曲即可:

确定传入的参数:传入给定的二维空间图,传入记录遍历情况的图,传入特定点的坐标。

确定终止条件:当我们遍历到的点是已经走过的或者是不符合条件的就停止搜索。

处理路径:

我们引入一个二维的数组visit来记录每个点的访问情况,当传入一个点时,我们直接将其标记为已访问过,然后我们利用opt数组来向四个方向进行搜索,如果搜索的点合法我们继续递归搜索。

在住函数中我们遍历整张图如果遍历到一点为符合搜索条件的点并且没有被访问过我们就将count+1,然后继续搜索。

cpp 复制代码
class Solution {
public:
    int opt[4][2] = {1,0,0,-1,0,1,-1,0};
    void dfs(vector<vector<char>>& graph, vector<vector<bool>>& visited, int x, int y){
        if(graph[x][y] == '0' || visited[x][y] == true){
            return;
        }
        visited[x][y] = true;
        for(int i = 0; i < 4; i++){
            int nextx = x + opt[i][0];
            int nexty = y + opt[i][1];
            if(nextx >= 0 && nexty >= 0 && nextx < graph.size() && nexty < graph[0].size()){
                dfs(graph, visited, nextx, nexty);
            }
            else continue;
        }
    }
    int numIslands(vector<vector<char>>& grid) {
        vector<vector<bool>> visited(grid.size(), vector<bool>(grid[0].size(), false));
        int count = 0;
        for(int i = 0; i < grid.size(); i++){
            for(int j = 0; j < grid[0].size(); j++){
                if(grid[i][j] == '1' && !visited[i][j]){
                    count++;
                    dfs(grid, visited, i, j);
                }
            }
        }
        return count;
    }
};

注意的点就是判断点的合法情况。

相关推荐
愚戏师42 分钟前
Linux复习笔记(六)shell编程
linux·笔记·shell
.(ᗜ ˰ ᗜ) .1 小时前
机器学习笔记2
笔记
小葡萄20252 小时前
黑马程序员c++2024版笔记 第一章 变量和基本类型
笔记·c++20
顾子茵2 小时前
计算机图形学基础--Games101笔记(一)数学基础与光栅化
笔记·图形渲染
黄暄2 小时前
初识计算机网络。计算机网络基本概念,分类,性能指标
笔记·学习·计算机网络·考研
WarPigs2 小时前
Unity光照笔记
笔记·unity·游戏引擎
Alice-YUE3 小时前
【HTML5学习笔记1】html标签(上)
前端·笔记·学习·html·html5
Alice-YUE3 小时前
【HTML5学习笔记2】html标签(下)
前端·笔记·html·html5
jerry6093 小时前
LLM笔记(五)概率论
人工智能·笔记·学习·概率论
烧火大爷4 小时前
现代计算机图形学Games101入门笔记(十四)
笔记