LeetCode 207. Course Schedule【Java】

题目描述

207. 课程表

AC代码

题目需要解决的问题是:给定课程总量以及它们的先决条件,判断能不能学完这些课。

啥时候这个排课表没法进行呢,如果学课程A之前必须学B,学课程B之前必须学A,那这样的话课表是不可能拍出来的,所以这个问题可以转化为看看存不存在一个环的问题。学课程B之前必须学A,这样的关系有一个前驱有一个后继,我们可以认为是有一个方向存在的,如果这个课表可以被排出来,那么各门课程应该可以组成一个有向无环图,判断一个有向无环图是否有环的方法就是用拓扑排序来解决。

🌙之前我们学习到拓扑排序的工作流程如下:

  • 在有向图中选一个没有前驱的顶点且输出它

  • 从图中删除该顶点和所有以他为尾的弧

  • 重复上述两步,直到全部顶点都输出或者图中不存在无前驱的顶点为止。

    这样得到的序列就是一个拓扑序列。

那么这道题,我们就可以BFS去做这个拓扑排序。
算法流程:

  • 统计课程安排图中每个节点的入度情况,保存在degree数组中。将课程之前的依赖关系通过set保存,借助一个队列q,将所有入度为0的节点入队,入度为0说明学习该门课程不需要其它先决条件。
  • 当 queue 非空时,依次将队首节点cur出队,然后查找set集合,将其对应的邻接节点next的入度情况-1,也就是degree[next]--。如果它的入度情况为0了,此时该节点没有前驱,也就是说学习该门课程之前不需要再学习其他课程了,所以这门课可以入队了。
  • 每一次我们都会用cnt变量去保存节点的个数,如果这个课表无法成功也就是存在环的话,那么我们记录的节点个数肯定和课程数目不相同,如果相同就说明可以排课。
class Solution {
    public boolean canFinish(int n, int[][] array) {
        HashSet<Integer>[] set = new HashSet[n];
        int[] degree=new int[n]; //记录入度
        for (int i = 0; i < n; i++) {
            set[i] = new HashSet<>();
        }
        for(int[] x:array){
            set[x[1]].add(x[0]);
            degree[x[0]]++;
        }
        int cnt=0;
        Queue<Integer> q=new LinkedList<>();
        //从入度为0的节点,也就是没有前驱的节点开始拓扑排序
        for(int i=0;i<n;i++)
            if(degree[i]==0)
                q.add(i);
        while(!q.isEmpty()){
            int cur=q.peek();
            q.poll();
            cnt++;
            for(int next:set[cur]){
                degree[next]--;
                if(degree[next]==0)
                    q.add(next);
            }
        }
        return cnt==n;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值