美文网首页
LeetCode 第207题:课程表

LeetCode 第207题:课程表

作者: 放开那个BUG | 来源:发表于2020-08-20 00:10 被阅读0次

1、前言

题目描述

2、思路

使用拓扑排序的方法,拓扑排序其实是使用的 BFS 算法,简而言之使用 BFS 算法解题。算法流程如下:

  • 1、统计课程安排图中每个节点的入度,生成入度表 indegrees
  • 2、借助一个队列 queue,将所有入度为0的节点入队
  • 3、当 queue 非空时,依次将队首节点出队,在课程安排图中删除此节点 pre:
    1⃣️ 并不是真正从邻接表中删除此节点 pre,而是将此节点对应所有邻接节点 cur 的入度 -1,即 indegrees[cur] -= 1。
    2⃣️ 当入度减1后邻接节点 cur 的入度为0,说明 cur 所有的前驱节点已经被“删除”,此时将 cur 入队
  • 4、在每次 pre 出队时,执行 numCourses--
    1⃣️ 若整个课程安排图是有向无环图,则所有节点一定都入队并出队过,即完成拓扑排序。换个角
    度,若课程安排图中存在环,一定有节点的入度始终不为0.
    2⃣️ 所以,拓扑排序出队次数等于课程个数,返回 numCourses == 0 判断课程是否被成功安排。

或者使用图遍历的方法。

3、代码

拓扑排序:

class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        int[] indegrees = new int[numCourses];

        // 每个点对应的边
        Map<Integer, List<Integer>> adjacency = new HashMap<>();
        Queue<Integer> queue = new LinkedList<>();
        for(int i = 0; i < numCourses; i++){
            adjacency.put(i, new ArrayList<>());
        }

        // 二维数组,每一行有两列,即两个值,代表 cp[1] -> cp[0] 的方向
        for(int[] cp : prerequisites){
            indegrees[cp[0]]++;
            adjacency.get(cp[1]).add(cp[0]);
        }

        // 将入度为0的顶点加入队列
        for(int i = 0; i < numCourses; i++){
            if(indegrees[i] == 0){
                queue.offer(i);
            }
        }

        // BFS
        while(!queue.isEmpty()){
            int pre = queue.poll();
            numCourses--;
            for(int cur : adjacency.get(pre)){
                if(--indegrees[cur] == 0){
                    queue.offer(cur);
                }
            }
        }

        return numCourses == 0;
    }
}

图遍历:

class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        List<List<Integer>> graphList = new ArrayList<>();
        for(int i = 0; i < numCourses; i++){
            graphList.add(new ArrayList<>());
        }
        for(int[] pre : prerequisites){
            int from = pre[1], to = pre[0];
            graphList.get(from).add(to);
        }

        int[] visited = new int[numCourses];
        for(int i = 0; i < numCourses; i++){
            if(dfs(graphList, i, visited)){
                return false;
            }
        }
        return true;
    }

    private boolean dfs(List<List<Integer>> graphList, int course, int[] visited){
        // 正在访问中,并且又到了之前记录的访问中,说明有环
        if(visited[course] == 1){
            return true;
        }

        // 已经访问过了
        if(visited[course] == 2){
            return false;
        }

        visited[course] = 1;
        for(Integer nerberCourse : graphList.get(course)){
            if(dfs(graphList, nerberCourse, visited)){
                return true;
            }
        }
        visited[course] = 2;
        return false;
    }
}

相关文章

  • LeetCode-207-课程表

    LeetCode-207-课程表 207. 课程表[https://leetcode-cn.com/problem...

  • LeetCode 第207题:课程表

    1、前言 2、思路 使用拓扑排序的方法,拓扑排序其实是使用的 BFS 算法,简而言之使用 BFS 算法解题。算法流...

  • LeetCode 207. 课程表 | Python

    207. 课程表 题目来源:力扣(LeetCode)https://leetcode-cn.com/problem...

  • LeetCode算法题-Add Digits(Java实现-3种

    这是悦乐书的第199次更新,第207篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第...

  • LeetCode算法题-Intersection of Two

    这是悦乐书的第207次更新,第219篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第...

  • LeetCode 207. 课程表

    题目 207. 课程表 题目描述 现在你总共有 n 门课需要选,记为 0 到 n-1。在选修某些课程之前需要一些先...

  • LeetCode 207. 课程表

    1、题目 课程表 - 力扣(LeetCode) https://leetcode-cn.com/problems/...

  • leetcode207 课程表

    题目 现在你总共有 n 门课需要选,记为 0 到 n-1。 在选修某些课程之前需要一些先修课程。 例如,想要学习课...

  • leetcode-207-课程表

    问题描述: 现在你总共有n门课需要选,记为0到n-1。 在选修某些课程之前需要一些先修课程。 例如,想要学习课程 ...

  • Leetcode207:课程表

    【题目描述】你这个学期必须选修 numCourse 门课程,记为 0 到 numCourse-1 。 在选修某些课...

网友评论

      本文标题:LeetCode 第207题:课程表

      本文链接:https://www.haomeiwen.com/subject/bjwddktx.html