课程表-拓扑排序-力扣207

60 阅读1分钟

课程表-力扣207

拓扑排序模板-深度搜索dfs版解法

核心思想,从某个点出发向下一直深搜,确保没有环即可确定存在拓扑序列

class Solution {
public:
    vector<vector<int>> edges;
    vector<int> visited;
    bool valid = true;

    void dfs(int u){
        visited[u] = 1; // 标记当前结点被访问过
        int len = edges[u].size();//当前结点有多少条边

        for(int i = 0; i < len; i ++){ //访问当前结点指向的所有结点
            int v = edges[u][i]; //结点u的边表
            if(visited[v] == 0){ //如果下一个结点没有被访问过
                dfs(v);
                if(!valid) return; //如果出递归栈后,发现不存在拓扑序列(有环),则直接返回
            }else if(visited[v] == 1){//发现下一个结点被访问过,说明有环,则直接返回false
                valid = false;
                return;
            }
        }

        visited[u] = 2; //输出拓扑序列,
    }

    bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
        edges.resize(numCourses);
        visited.resize(numCourses);

        vector<int> edge;
        int len = prerequisites.size();  //记录有多少条边
        for(int i = 0; i < len; i ++){// 将输入数据转换为边
            edge = prerequisites[i];
            edges[edge[1]].push_back(edge[0]);
        }

        for(int i = 0; i < numCourses && valid; i ++){
            if(!visited[i]){
                dfs(i);
            }
        }

        return valid;
    }
};

时间复杂度: O(n+m)O(n+m),其中 nn 为课程数,mm 为先修课程的要求数。

空间复杂度: O(n+m)O(n+m)。题目中是以列表形式给出的先修课程关系,为了对图进行深度优先搜索,我们需要存储成邻接表的形式,空间复杂度为 O(n+m)O(n+m)。在深度优先搜索的过程中,我们需要最多 O(n)O(n) 的栈空间(递归)进行深度优先搜索,因此总空间复杂度为 O(n+m)O(n+m)