207. Course Schedule(课程计划)

以前做的关于图的题比较少,因此这次做这题感觉到相当的难度。虽然之后是想到了要用DFS或者BFS来解题,但是一直想用堆栈、队列来做,苦于能力不行,最后只能上网查询拓扑算法的DFS、BFS做法,并且不再纠结于一定要使用堆栈或者队列,之后便能顺利解决了。总的来说这道题价值很大,第一次对图算法有了一点理解。


关于这道题,先说说BFS做法,个人觉得更为简单。首先利用vector做出一个二维数组的graph图以供搜索,同时利用一个indegree数组记录所有课程的入度然后将入度为0的课程加入到队列中。循环队列,移除当前入度为0的课程,并根据图把入度为0的课程所对应的后续课程的入度-1,若存在后续课程入度为0,加入队列,不断循环直至队列为空。若移除的课程数等于总课程数,则不存在环,否则存在。

class Solution {
public:
    bool canFinish(int numCourses, vector>& prerequisites) {
        vector> graph(numCourses, vector(0));
        vector indegree(numCourses, 0);
        queue q;
        
        for (auto t : prerequisites) {
            graph[t.second].push_back(t.first);
            indegree[t.first]++;
        }
        int i;
        for (i = 0; i < indegree.size(); i++) {
            if (!indegree[i])
                q.push(i);
        }
        int count = 0;
        while (!q.empty()) {
            for (auto t : graph[q.front()]) {
                indegree[t]--;
                if (!indegree[t])
                    q.push(t);
            }
            q.pop();
            count++;
        }
        return count == numCourses;
    }
};

接下来说说DFS的做法。类似的要利用vector做出一个用于搜索的graph图,并且利用一个visit数组记录每一个课程的当前状态,0代表未访问,1代表已访问且正确,-1代表不可访问且错误。对每一个课程都进行一次DFS,同时对于某一个课程的所有后续课程都进行一次DFS,若所有后续课程都均可返回true,证明此课程不存在环,因此visit=1代表此课程已访问且正确,否则此课程就是不可访问且错误。

bool DFS(vector>& graph, vector& visit, int i) {
	if (visit[i] == -1)
		return false;
	if (visit[i] == 1)
		return true;
	visit[i] = -1;//等于-1代表不可重复
	for (auto t : graph[i]) {
		if (!DFS(graph, visit, t))
			return false;
	}
	visit[i] = 1;//等于1代表已访问
	return true;
}

class Solution {
public:
    bool canFinish(int numCourses, vector>& prerequisites) {
        vector visit(numCourses, 0);
        vector> graph(numCourses, vector(0));

        for (auto t : prerequisites) {
            graph[t.first].push_back(t.second);
        }

        for (int i = 0; i < graph.size(); i++) {
            if (!DFS(graph, visit, i))
                return false;
        }
        return true;
    }
};


你可能感兴趣的:(算法)