【Leetcode】210. Course Schedule II(代码实现)

97 阅读1分钟

题目地址:

leetcode.com/problems/co…

屏幕截图 2022-01-15 135818.png

import java.util.*;

public class Solution {
    public int[] findOrder(int numCourses, int[][] prerequisites) {
        int[] res = new int[numCourses];
        if (prerequisites == null || prerequisites.length == 0) {
            for (int i = 0; i < numCourses; i++) {
                res[i] = i;
            }
            return res;
        }
    
        Map<Integer, List<Integer>> graph = buildGraph(prerequisites);
        int[] indegrees = new int[numCourses];
        for (int[] prerequisite : prerequisites) {
            indegrees[prerequisite[0]]++;
        }
        
        Queue<Integer> queue = new LinkedList<>();
        for (int i = 0; i < indegrees.length; i++) {
            if (indegrees[i] == 0) {
                queue.offer(i);
            }
        }
        
        int idx = 0;
        while (!queue.isEmpty()) {
            int cur = queue.poll();
            // 每次出队一个数就将其加入答案数组中
            res[idx++] = cur;
            if (graph.containsKey(cur)) {
                for (int next : graph.get(cur)) {
                	// 将邻居节点入度减少1
                    indegrees[next]--;
                    // 如果入度减少到0,则加入队列
                    if (indegrees[next] == 0) {
                        queue.offer(next);
                    }
                }
            }
        }
        
        return idx != numCourses ? new int[0] : res;
    }
    
    private Map<Integer, List<Integer>> buildGraph(int[][] prerequisites) {
        Map<Integer, List<Integer>> map = new HashMap<>();
        for (int[] prerequisite : prerequisites) {
            map.putIfAbsent(prerequisite[1], new ArrayList<>());
            map.get(prerequisite[1]).add(prerequisite[0]);
        }
        
        return map;
    }
}

屏幕截图 2022-01-15 140010.png

import java.util.*;

public class Solution {
    public int[] findOrder(int numCourses, int[][] prerequisites) {
        int[] res = new int[numCourses];
        if (prerequisites == null || prerequisites.length == 0) {
            for (int i = 0; i < numCourses; i++) {
                res[i] = i;
            }
            return res;
        }
    
        Map<Integer, List<Integer>> graph = buildGraph(prerequisites);
        Deque<Integer> stack = new LinkedList<>();
        int[] visited = new int[numCourses];
        Arrays.fill(visited, -1);
        for (int i = 0; i < numCourses; i++) {
            if (visited[i] == -1) {
            	// 如果发现了环,则直接返回空数组
                if (dfs(i, graph, visited, stack)) {
                    return new int[0];
                }
            }
        }
        
        int idx = 0;
        while (!stack.isEmpty()) {
            res[idx++] = stack.pop();
        }
        
        return res;
    }
    
    // 函数功能是,从cur开始做DFS,并按照递归返回的顺序将访问过的顶点入栈;
    // 返回是否发现了环;如果有环则返回true,否则返回false
    private boolean dfs(int cur, Map<Integer, List<Integer>> graph, int[] visited, Deque<Integer> stack) {
    	// 标记当前点为正在访问
        visited[cur] = 0;
        if (graph.containsKey(cur)) {
            for (int next : graph.get(cur)) {
            	// 如果发现某个邻居在本次DFS时访问过,说明有环,返回true;
            	// 否则如果邻居未访问,则对其进行访问
                if (visited[next] == 0) {
                    return true;
                } else if (visited[next] == -1) {
                    if (dfs(next, graph, visited, stack)) {
                        return true;
                    }
                }
            }
        }
        // 递归返回前要标记当前顶点为已访问过
        visited[cur] = 1;
        // 递归返回前要把当前顶点进栈
        stack.push(cur);
        return false;
    }
    
    private Map<Integer, List<Integer>> buildGraph(int[][] prerequisites) {
        Map<Integer, List<Integer>> map = new HashMap<>();
        for (int[] prerequisite : prerequisites) {
            map.putIfAbsent(prerequisite[1], new ArrayList<>());
            map.get(prerequisite[1]).add(prerequisite[0]);
        }
        
        return map;
    }
}