Application of graph - topological sorting

log all paths

class Solution {
    // 记录所有路径
    List<List<Integer>> res = new LinkedList<>();
        
    public List<List<Integer>> allPathsSourceTarget(int[][] graph) {
        // 维护递归过程中经过的路径
        LinkedList<Integer> path = new LinkedList<>();
        traverse(graph, 0, path);
        return res;
    }

    /* 图的遍历框架 */
    void traverse(int[][] graph, int s, LinkedList<Integer> path) {
        // 添加节点 s 到路径
        path.addLast(s);

        int n = graph.length;
        if (s == n - 1) {
            // 到达终点
            res.add(new LinkedList<>(path));
            // 可以在这直接 return,但要 removeLast 正确维护 path
            // path.removeLast();
            // return;
            // 不 return 也可以,因为图中不包含环,不会出现无限递归
        }

        // 递归每个相邻节点
        for (int v : graph[s]) {
            traverse(graph, v, path);
        }
        
        // 从路径移出节点 s
        path.removeLast();
    }
}

topic one

You must take numCourses courses this semester, numbered from 0 to numCourses - 1 .

Some prerequisite courses are required before taking certain courses. The prerequisites are given as an array prerequisites , where prerequisites[i] = [ai, bi] , indicating that if you want to take course ai you must first take course bi .

For example, the prerequisite course pair [0, 1] means: To take course 0, you need to have completed course 1 first.
Please judge whether it is possible to complete all courses of study? If so, return true; otherwise, return false.

Example 1:

Input: numCourses = 2, prerequisites = [[1,0]]
Output: true
Explanation: There are 2 courses in total. You need to complete Lesson 0 before taking Lesson 1. this is possible.
Example 2:

Input: numCourses = 2, prerequisites = [[1,0],[0,1]]
Output: false
Explanation: There are 2 courses in total. Before taking Course 1, you need to complete ​Lesson 0; and before taking Course 0, you should also complete Course 1. it's out of the question.

class Solution {
    boolean[] visited;//给已遍历的节点做标记
    boolean[] onPath;//记录路径上通过的节点
    boolean hasCycle;//判断是否有环
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        List<Integer>[] graph=buildGraph(numCourses,prerequisites);
        visited=new boolean[numCourses];
        onPath=new boolean[numCourses];
        for(int i=0;i<numCourses;i++){
            traverse(graph,i);
        }
        return !hasCycle;
    }
    // 邻接表
    // 转换为有向图
    List<Integer>[] buildGraph(int numCourses, int[][] prerequisites){
        List<Integer>[] graph=new LinkedList[numCourses];//每个节点对应一个链表
        for(int i=0;i<graph.length;i++){
            graph[i]=new LinkedList<>();
        }
        for(int[] edge:prerequisites){
            int from=edge[1],to=edge[0];
            //修完课程from才能修to课程
            graph[from].add(to);
        }
        return graph;
    }

    // 遍历
    void traverse(List<Integer>[] graph,int s){
        if(onPath[s]){
            hasCycle=true;
        }
        if(visited[s]||hasCycle){
            return;
        }
        visited[s]=true;
        onPath[s]=true;
        for(int t:graph[s]){
            traverse(graph,t);
        }
        onPath[s]=false;
    }
}

Topic two

Now you have a total of numCourses courses to take, denoted as 0 to numCourses - 1. You are given an array prerequisites, where prerequisites[i] = [ai, bi], which means that you must take bi before taking course ai.

For example, to learn course 0, you need to have completed course 1 first, which we denote by a match: [0,1] .
Returns the sequence of studies you have placed in order to complete all courses. There may be more than one correct order, you just need to return any one. Returns an empty array if it is not possible to complete all courses.

Example 1:

Input: numCourses = 2, prerequisites = [[1,0]]
Output: [0,1]
Explanation: There are 2 courses in total. To study Lesson 1, you need to have completed Lesson 0 first. So the correct class order is [0,1].
Example 2:

Input: numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]]
Output: [0,2,1,3]
Explanation: There are 4 courses in total course. To study Course 3, you should have completed Course 1 and Course 2 first. And both Course 1 and Course 2 should come after Course 0.
Therefore, a correct class order is [0,1,2,3] . Another correct ordering is [0,2,1,3] .
Example 3:

Input: numCourses = 1, prerequisites = []
Output: [0]

class Solution {
    // 记录后序遍历结果
    List<Integer> postorder = new ArrayList<>();
    // 记录是否存在环
    boolean hasCycle = false;
    boolean[] visited, onPath;

    // 主函数
    public int[] findOrder(int numCourses, int[][] prerequisites) {
        List<Integer>[] graph = buildGraph(numCourses, prerequisites);
        visited = new boolean[numCourses];
        onPath = new boolean[numCourses];
        // 遍历图
        for (int i = 0; i < numCourses; i++) {
            traverse(graph, i);
        }
        // 有环图无法进行拓扑排序
        if (hasCycle) {
            return new int[]{};
        }
        // 逆后序遍历结果即为拓扑排序结果
        Collections.reverse(postorder);
        int[] res = new int[numCourses];
        for (int i = 0; i < numCourses; i++) {
            res[i] = postorder.get(i);
        }
        return res;
    }

    // 图遍历函数
    void traverse(List<Integer>[] graph, int s) {
        if (onPath[s]) {
            // 发现环
            hasCycle = true;
        }
        if (visited[s] || hasCycle) {
            return;
        }
        // 前序遍历位置
        onPath[s] = true;
        visited[s] = true;
        for (int t : graph[s]) {
            traverse(graph, t);
        }
        // 后序遍历位置
        postorder.add(s);
        onPath[s] = false;
    }

    // 建图函数
    List<Integer>[] buildGraph(int numCourses, int[][] prerequisites) {
        // 代码见前文
        List<Integer>[] graph=new LinkedList[numCourses];
        for(int i=0;i<graph.length;i++){
            graph[i]=new LinkedList<>();
        }
        for(int[] edge:prerequisites){
            int from=edge[1],to=edge[0];
            graph[from].add(to);
        }
        return graph;
    }
}

 

 

 

 

Guess you like

Origin blog.csdn.net/bubbleJessica/article/details/129769309
Recommended