Course Schedule && Course Schedule ||

Course Schedule && Course Schedule ||

For Course Schedule
Problem description: There are a total of n courses you have to take, labeled from 0 to n - 1. Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]

Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses?

Example
Given n = 2, prerequisites = [[1,0]]
Return true

Given n = 2, prerequisites = [[1,0],[0,1]]
Return false

题目意思是说某些课程要上的话有先修课程的要求,比如要修Java web开发那么就需要修过java,某些学校的选课系统就有此限制。那么很显然这道题我们会想到结题思想就是拓扑排序(topological sort)。
拓扑排序对应施工的流程图具有特别重要的作用,它可以决定哪些子工程必须要先执行,哪些子工程要在某些工程执行后才可以执行。为了形象地反映出整个工程中各个子工程(活动)之间的先后关系,可用一个有向图来表示,图中的顶点代表活动(子工程),图中的有向边代表活动的先后关系,即有向边的起点的活动是终点活动的前序活动,只有当起点活动完成之后,其终点活动才能进行。通常,我们把这种顶点表示活动、边表示活动间先后关系的有向图称做顶点活动网(Activity On Vertex network),简称AOV网。
一个AOV网应该是一个有向无环图,即不应该带有回路,因为若带有回路,则回路上的所有活动都无法进行(对于数据流来说就是死循环)。在AOV网中,若不存在回路,则所有活动可排列成一个线性序列,使得每个活动的所有前驱活动都排在该活动的前面,我们把此序列叫做拓扑序列(Topological order),由AOV网构造拓扑序列的过程叫做拓扑排序(Topological sort)。AOV网的拓扑序列不是唯一的,满足上述定义的任一线性序列都称作它的拓扑序列。
所以在此题中我们只需要构建出拓扑序列,判断是否具有环即可,如有环,则表示不能修完这些课程,若无环,则表示可以修完这些课程。先贴代码:

public boolean canFinish(int numCourses, int[][] prerequisites) {
        // write your code here
        int[] inDegree = new int[numCourses];
        if(prerequisites == null || prerequisites.length == 0){
            return true;
        }
        HashMap<Integer, List<Integer>> graph = new HashMap<Integer, List<Integer>>();
        for(int i = 0; i < prerequisites.length; i++){
            inDegree[prerequisites[i][0]]++;

            if(graph.containsKey(prerequisites[i][1])){
                graph.get(prerequisites[i][1]).add(prerequisites[i][0]);
            }else{
                ArrayList<Integer> list = new ArrayList();
                list.add(prerequisites[i][0]);
                graph.put(prerequisites[i][1], list);
            }
        }

        LinkedList<Integer> queue = new LinkedList();

        for(int i = 0; i < numCourses; i++){
            if(inDegree[i] == 0){
                queue.offer(i);
            }
        }

        while(!queue.isEmpty()){
            int course = queue.poll();
            List<Integer> subcourses = graph.get(course);
            for(int i = 0; subcourses != null && i < subcourses.size(); i++){
                if(--inDegree[subcourses.get(i)] == 0){
                    queue.offer(subcourses.get(i));
                }
            }
        }

        for(int i = 0; i < numCourses; i++){
            if(inDegree[i] != 0){
                return false;
            }
        }
        return true;
    }

代码解释:首先我们需要根据传入和数据构建图,根据课程依赖关系的二维数组,可以统计出各个课程的入度(indegree),然后利用HashMap来构建图,注意key是先修课程,而value是一个list,代表那些依赖于key的后续课程。当这些初始化工作完成后,我们只需要用BFS遍历该图,维护一个queue,初始时队列中只有无依赖关系的可以直接上的课,每当pop出一个值时,与该课程有依赖关系的后续课程的入度减去1,当其减少至0时,代表该课程所需的先修课程已经全部完成,故将该课程也放入队列中,当队列为空时,遍历完成。此时只需要检查入度即可判断。

For Course Schedule ||
There are a total of n courses you have to take, labeled from 0 to n - 1.
Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1]

Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses.

There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.

Example
Given n = 2, prerequisites = [[1,0]]
Return [0,1]

Given n = 4, prerequisites = [1,0],[2,0],[3,1],[3,2]]
Return [0,1,2,3] or [0,2,1,3]

跟第一题相比,只是多了需要我们输出上课顺序,结题思路和第一题一模一样,利用一个一维数组记录上课顺序即可,代码如下:

public int[] findOrder(int numCourses, int[][] prerequisites) {
        // write your code here
        int[] inDegree = new int[numCourses];
        int[] results = new int[numCourses];
        int last = 0;

        if(prerequisites == null || numCourses < 0){
            return results;
        }

        if(prerequisites.length == 0){
            for(int i=0; i<numCourses; i++){
                results[i] = i;
            }
            return results;
        }

        HashMap<Integer, List<Integer>> graph = new HashMap<Integer, List<Integer>>();
        for(int i = 0; i < prerequisites.length; i++){
            inDegree[prerequisites[i][0]]++;

            if(graph.containsKey(prerequisites[i][1])){
                graph.get(prerequisites[i][1]).add(prerequisites[i][0]);
            }else{
                ArrayList<Integer> list = new ArrayList();
                list.add(prerequisites[i][0]);
                graph.put(prerequisites[i][1], list);
            }
        }

        LinkedList<Integer> queue = new LinkedList();

        for(int i = 0; i < numCourses; i++){
            if(inDegree[i] == 0){
                queue.offer(i);
            }
        }

        last = queue.size();        
        for(int i=0; i<queue.size(); i++){
            results[i] = queue.get(i);
        }

        while(!queue.isEmpty()){
            int course = queue.poll();
            List<Integer> subcourses = graph.get(course);
            for(int i = 0; subcourses != null && i < subcourses.size(); i++){
                if(--inDegree[subcourses.get(i)] == 0){
                    queue.offer(subcourses.get(i));
                    results[last] = subcourses.get(i);
                    last++;
                }
            }
        }

        for(int i = 0; i < numCourses; i++){
            if(inDegree[i] != 0){
                return new int[0];
            }
        }
        return results;
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java,ClassNotFoundException是一种异常型,表示在运行时找不到指定的。当使用Class.forName()方法或ClassLoader.loadClass()方法加载时,如果找不到指定的,就会抛出ClassNotFoundException异常。 对于你提到的ClassNotFoundException: CourseSchedule异常,它表示在运行时无法找到名为CourseSchedule。这可能是由于以下几个原因导致的: 1. 名拼写错误:请确保你输入的名正确无误。Java名是区分大小写的,所以请检查名的大小写是否与实际名一致。 2. 缺少依赖:如果CourseSchedule依赖于其他或库,而这些依赖项没有正确地被包含在项目,就会导致ClassNotFoundException异常。请确保所有依赖项都已正确添加到项目。 3. 路径问题:如果CourseSchedule所在的包或目录没有被正确地包含在路径,也会导致ClassNotFoundException异常。请检查路径设置,确保包含了CourseSchedule所在的路径。 解决这个问题的方法取决于你的具体情况。如果是第一种情况,你可以检查名的拼写是否正确。如果是第二种情况,你需要确保所有依赖项都已正确添加到项目。如果是第三种情况,你需要检查路径设置是否正确。 如果你能提供更多的上下文信息,比如你是在什么情况下遇到这个异常,以及你的代码或项目结构,我可以给出更具体的解决方案。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值