LeetCode刷题之HOT100之课程表

吃完普通的食堂饭菜,回到实验室,继续做一道题!

1、题目描述

在这里插入图片描述

2、逻辑分析

这道题涉及到图相关知识,应用到了拓扑排序。
题意解释

  • 一共有 n 门课要上,编号为 0 ~ n-1。
  • 先决条件 [1, 0],意思是必须先上课 0,才能上课 1。
  • 给你 n、和一个先决条件表,请你判断能否完成所有课程。

官方给的题解太抽象了,有另一个题解给的很直观,易理解,放过来:题解:课程表

3、代码演示

public boolean canFinish(int numCourses, int[][] prerequisites) {
        // 创建一个哈希映射,用于存储每个课程的入度(即需要先修的课程数量)
        Map<Integer, Integer> inDegree = new HashMap<>();
        // 初始化每个课程的入度为0 
        for(int i = 0; i < numCourses; i++){
            inDegree.put(i,0);
        }

        // 创建一个哈希映射,用于存储每个课程的后续课程列表
        Map<Integer, List<Integer>> adj = new HashMap<>();

        // 遍历先决条件数组 
        for(int[] relate : prerequisites){
            // 当前课程(即需要学习的课程)
            int cur = relate[1];
            // 后续课程(即当前课程的先决条件)
            int next = relate[0];

            // 更新后续课程的入度
            inDegree.put(next, inDegree.get(next) + 1);

            // 如果当前课程的后续课程列表还未初始化,则进行初始化
            if(!adj.containsKey(cur)){
                adj.put(cur, new ArrayList<>());
            }

            // 将后续课程添加到当前课程的后续课程列表中
            adj.get(cur).add(next);
        }

        // 创建一个队列,用于存储入度为0的课程
        Queue<Integer> queue = new LinkedList<>();
        // 将所有入度为0的课程加入队列
        for(int key : inDegree.keySet()){
            if(inDegree.get(key) == 0){
                queue.offer(key);
            }
        }
        // 拓扑排序的主循环
        while(!queue.isEmpty()){
            // 取出队首的入度为0的课程  
            int cur = queue.poll();
            // 如果当前课程没有后续课程(即没有需要它作为先决条件的课程),则跳过此次循环
            if(! adj.containsKey(cur)){
                continue;
            }
            List<Integer> successorList = adj.get(cur);
            // 遍历当前课程的后续课程列表 
            for(int k : successorList){
                // 更新后续课程的入度
                inDegree.put(k, inDegree.get(k) - 1);
                // 如果后续课程的入度变为0,则将其加入队列
                if(inDegree.get(k) == 0){
                    queue.offer(k);
                }
            }
        }
        // 遍历所有课程的入度,如果有任何课程的入度不为0,则说明存在环,无法完成所有课程
        for(int key : inDegree.keySet()){
            if(inDegree.get(key) != 0){
                return false;
            }
        }
        // 所有课程的入度都为0,说明不存在环,可以完成所有课程 
        return true;
    }

哈哈,击败百分之十二,笑了!照着打的,看了半天还是不太懂,懂了我下次做估计也做不出来,先放这儿吧,下次再来看!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值