207. Course Schedule(课程计划)

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


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

class Solution {
public:
    bool canFinish(int numCourses, vector<pair<int, int>>& prerequisites) {
        vector<vector<int>> graph(numCourses, vector<int>(0));
        vector<int> indegree(numCourses, 0);
        queue<int> 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<vector<int>>& graph, vector<int>& 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<pair<int, int>>& prerequisites) {
        vector<int> visit(numCourses, 0);
        vector<vector<int>> graph(numCourses, vector<int>(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;
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
courseschedule代表整个课程注册系统,而类course则代表具体的课程。 在类courseschedule中,我们可以定义一些属性和方法来管理和操作课程信息。比如: 1. 属性: - courses:一个列表,用来储存所有已注册的课程对象。 2. 方法: - add_course(course):将一个课程对象添加到courses列表中。 - remove_course(course):从courses列表中移除一个课程对象。 - search_course(course_name):根据课程名称搜索并返回对应的课程对象。 - get_all_courses():返回courses列表中的所有课程对象。 - count_courses():返回已注册的课程数量。 - check_conflict(course):检查某个课程对象是否与已注册的课程时间冲突。 - generate_schedule():根据已注册的课程生成课程表。 在类course中,我们可以定义一些属性和方法来描述和管理课程的具体信息。比如: 1. 属性: - course_name:课程名称。 - course_code:课程代码。 - instructor:授课教师。 - schedule:课程时间安排。 2. 方法: - get_course_name():返回课程名称。 - get_course_code():返回课程代码。 - get_instructor():返回授课教师。 - get_schedule():返回课程时间安排。 通过两个类的定义和相应的方法,我们可以在课程注册系统中实现课程的注册、查询、删除、时间冲突检查和生成课程表等功能。这样可以方便学生和教师管理自己的课程信息,并避免时间冲突的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值