美文网首页
207. 课程表

207. 课程表

作者: justonemoretry | 来源:发表于2021-08-30 22:28 被阅读0次
image.png

解法

深度优先遍历解法

class Solution {

    private List<List<Integer>> edges = new ArrayList<>();
    // 对应课程,0代表未搜索,1代表搜索中,2代表已完成
    private int[] visited;
    private boolean valid = true;
    
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        visited = new int[numCourses];
        for (int i = 0; i < numCourses; i++) {
            edges.add(new ArrayList<>());
        }
        for (int[] p: prerequisites) {
            // 节点p[1]后面的节点有多少
            edges.get(p[1]).add(p[0]);
        }
        for (int i = 0; i < numCourses; i++) {
            if (visited[i] == 0) {
                dfs(i);
            }
        }
        return valid;
    }

    public void dfs(int i) {
        visited[i] = 1;
        for (int v : edges.get(i)) {
            // 后面节点未搜索,进行搜索
            if (visited[v] == 0) {
                dfs(v);
                if (!valid) {
                    return;
                }
            } else if (visited[v] == 1) {
                // 后面节点也在搜索中,说明有环,有环则说明不是拓扑排序
                valid = false;
                return;
            }
            // 后面节点已经搜索完成,说明有其它前置节点已经搜索过,并且已经搜索完成
        }
        visited[i] = 2;
    }
}

广度优先解法

class Solution {
    
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        // 每个节点的入度
        int[] inCount = new int[numCourses];
        List<List<Integer>> edges = new ArrayList<>();
        for (int i = 0; i < numCourses; i++) {
            edges.add(new ArrayList<>());
        }
        // 计算其中涉及到的边
        for (int[] p : prerequisites) {
            edges.get(p[1]).add(p[0]);
            inCount[p[0]]++;
        }
        // 存放入度为0的节点
        Queue<Integer> q = new LinkedList<>();
        for (int i = 0; i < numCourses; i++) {
            if (inCount[i] == 0) {
                q.offer(i);
            }
        }
        int size = 0;
        while (!q.isEmpty()) {
            size++;
            // 弹出入度为0的节点后,将相邻节点的入度减1
            int a = q.poll();
            List<Integer> nextList = edges.get(a);
            for (int next : nextList) {
                inCount[next] -= 1;
                // 入度为0的节点,还放到队列中
                if (inCount[next] == 0) {
                    q.offer(next);
                }
            }
        }
        return size == numCourses;
    }
}

相关文章

网友评论

      本文标题:207. 课程表

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