LeetCode--210--medium--CourseScheduleII

summary:

directed graph | dfs | topological sort 

package myapp.kit.leetcode.graph;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * 210
 * medium
 * https://leetcode.com/problems/course-schedule-ii/
 *
 *
 * 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, return the ordering of courses you should take to finish all courses.
 *
 * There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array.
 *
 * Example 1:
 *
 * Input: 2, [[1,0]]
 * Output: [0,1]
 * Explanation: There are a total of 2 courses to take. To take course 1 you should have finished
 *              course 0. So the correct course order is [0,1] .
 * Example 2:
 *
 * Input: 4, [[1,0],[2,0],[3,1],[3,2]]
 * Output: [0,1,2,3] or [0,2,1,3]
 * Explanation: There are a total of 4 courses to take. To take course 3 you should have finished both
 *              courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0.
 *              So one correct course order is [0,1,2,3]. Another correct ordering is [0,2,1,3] .
 * 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.
 *
 * Created with IDEA
 * author:Dingsheng Huang
 * Date:2020/4/16
 * Time:下午1:58
 */
public class CourseScheduleII {

    private static Integer NODE_COLOR_WHITE  = 0;

    private static Integer NODE_COLOR_GRAY = 1;

    private static Integer NODE_COLOR_BLACK = 2;

    private Map<Integer, List<Integer>> graph = new HashMap<>();

    private Map<Integer, Integer> color = new HashMap<>();

    private List<Integer> topologicalOrder = new ArrayList<>();

    private boolean cycle = false;

    private void dfs(Integer node) {
        if (cycle) {
            return;
        }
        color.put(node, NODE_COLOR_GRAY);
        for (Integer nextNode : graph.getOrDefault(node, new ArrayList<>())) {
            if (color.get(nextNode) == NODE_COLOR_WHITE) {
                dfs(nextNode);
            } else if (color.get(nextNode) == NODE_COLOR_GRAY) {
                cycle = true;
            } else {
                // black
                continue;
            }
        }
        color.put(node, NODE_COLOR_BLACK);
        topologicalOrder.add(node);
    }

    public int[] findOrder(int numCourses, int[][] prerequisites) {
        // color init
        for (int i = 0; i < numCourses; i++) {
            color.put(i, NODE_COLOR_WHITE);
        }
        // graph  init
        for (int[] pair : prerequisites) {
            List<Integer> neighbors = graph.getOrDefault(pair[1], new ArrayList<>());
            neighbors.add(pair[0]);
            graph.put(pair[1], neighbors);
        }
        for (int i = 0; i < numCourses; i++) {
            if (color.get(i) == NODE_COLOR_WHITE) {
                dfs(i);
                // pruning
                if (cycle) {
                    return new int[0];
                }
            }
        }
        if (cycle) {
            return new int[0];
        }
        int[] answer = new int[numCourses];
        for (int i = topologicalOrder.size() - 1; i >= 0; i--) {
            answer[numCourses - i - 1] = topologicalOrder.get(i);
        }
        return answer;
    }
}



发布了205 篇原创文章 · 获赞 27 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/huangdingsheng/article/details/105563757