晨哥Leetcode 207. 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, is it possible for you to finish all courses?
Example 1:
Input: 2, [[1,0]]
Output: true
Explanation: There are a total of 2 courses to take.
To take course 1 you should have finished course 0. So it is possible.
Example 2:
Input: 2, [[1,0],[0,1]]
Output: false
Explanation: There are a total of 2 courses to take.
To take course 1 you should have finished course 0, and to take course 0 you should
also have finished course 1. So it is impossible.
Note:
The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.
You may assume that there are no duplicate edges in the input prerequisites.

拓扑排序基本套路
第一步,建立degree数组,统计每个数的需要多少个前置的先修课程,degree为0就是不需要任何先修课程,直接可以上的课
第二步,把依赖关系记下来,edges[i] 存的是依赖于i这门课的都有哪些课
为什么不是反过来存呢?这样存的目的是当i这门课上完以后,我方便去查找哪些课的degree可以减一了。i是被依赖的课,所有依赖i的都存在edges[i]里, 当i被上了以后,也就是所有依赖i的课,都已经减少了一个依赖
第三步,先把所有degree为0,没有任何依赖的课都放到一个队列里去
第四步, 一个个从队列里取出课来上,每上完一门课,都把依赖于这个课的其他课degree -1, 那么当degree为0时,又可以加入到队列里去了

每上完一门课计数,count == courses number, 就是所有课都能上完

注意list[]的初始化
for(int i = 0; i<k; i++) {
edges[i] = new ArrayList(); //必须要这样初始化, Arrays.fill(edges, new ArrayList()) 是不对的,所有的元素都会指向同一个list对象
}

public boolean canFinish(int k, int[][] pre) {
        int[] degree = new int[k]; //degree数组,统计每个数的需要多少个前置的先修课程,degree为0就是不需要任何先修课程,直接可以上的课
        List[] edges= new ArrayList[k]; //list[] 这种操作有点意思,不过不方便加泛型
        for(int i = 0; i<k; i++) {
            edges[i] = new ArrayList(); //必须要这样初始化, Arrays.fill(edges, new ArrayList()) 是不对的,所有的元素都会指向同一个list对象
        }
        for(int[] cur: pre) {
            degree[cur[0]]++;
            edges[cur[1]].add(cur[0]); //理清关系就行
        }
        Queue<Integer> q = new LinkedList();
        for(int i = 0; i < k; i++) {
            if(degree[i] == 0) {
                q.offer(i);
            }
        }
        int count = 0;
        while(!q.isEmpty()) {
            Integer course = q.poll();
            count++;
            for(Object o : edges[course]) { //取出时做类型转换          
                int cur = (Integer)o;
                if(--degree[cur] == 0) {
                    q.offer(cur);
                }
            }
        }
        return count == k;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值