图论做题笔记: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;
    }
};

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

相关推荐
美式小田3 小时前
单片机学习笔记 9. 8×8LED点阵屏
笔记·单片机·嵌入式硬件·学习
猫爪笔记3 小时前
前端:HTML (学习笔记)【2】
前端·笔记·学习·html
_不会dp不改名_3 小时前
HCIA笔记3--TCP-UDP-交换机工作原理
笔记·tcp/ip·udp
-一杯为品-4 小时前
【51单片机】程序实验5&6.独立按键-矩阵按键
c语言·笔记·学习·51单片机·硬件工程
熙曦Sakura5 小时前
完全竞争市场
笔记
dr李四维6 小时前
iOS构建版本以及Hbuilder打iOS的ipa包全流程
前端·笔记·ios·产品运营·产品经理·xcode
Komorebi.py10 小时前
【Linux】-学习笔记05
linux·笔记·学习
亦枫Leonlew10 小时前
微积分复习笔记 Calculus Volume 1 - 6.5 Physical Applications
笔记·数学·微积分
冰帝海岸15 小时前
01-spring security认证笔记
java·笔记·spring
小二·16 小时前
java基础面试题笔记(基础篇)
java·笔记·python