207,210. Course Schedule I, II

来源:互联网 发布:软件设计师考试解析 编辑:程序博客网 时间:2024/05/18 16:18

Course Schedule I

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, is it possible for you to finish all courses?

For example:

2, [[1,0]]

There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.

2, [[1,0],[0,1]]

There are a total of 2 courses to take. To take course 1 you should have finished course 0, and to take course 0 you should also have finished course 1. So it is impossible.

Note:

The input prerequisites is a graph represented by a list of edges, not adjacency matrices. Read more about how a graph is represented.

思路:本题等同于图里找circle。 用DFS找circle。为剪枝,找到circle,直接停止(用个全局变量)。起始把数组转换成Hashmap便于DFS。

public class Solution {    public boolean findCircle = false;    public boolean canFinish(int numCourses, int[][] prerequisites) {        Map<Integer, List<Integer>> map = new HashMap<>();        for(int i=0; i<prerequisites.length; i++){            if(!map.containsKey(prerequisites[i][0])){                List<Integer> al = new ArrayList<>();                al.add(prerequisites[i][1]);                map.put(prerequisites[i][0],al);            }            else{                map.get(prerequisites[i][0]).add(prerequisites[i][1]);            }        }        boolean[] marked = new boolean[numCourses];        for(int i=0; i<numCourses; i++){            if(findCircle) break;            dfs(i,map,marked);        }        return !findCircle;    }    public void dfs(int n, Map<Integer, List<Integer>> map, boolean[] marked){        if(marked[n]){            findCircle=true;            return;        }        if(!map.containsKey(n) || findCircle) return;        List<Integer> al = map.get(n);        marked[n]=true;        for(int i=0; i<al.size(); i++){            if(findCircle) break;            dfs(al.get(i), map, marked);        }        marked[n]=false;    }}

思路2: BFS

先得到每个节点入度的数组in[]和所有入度为0的节点作为起始点集,开始BFS遍历,到一个点将其入度-1,如果入度为0,将其放到起始点集中,最后如果起始点集中元素个数大于总节点个数,则有圈。

Course Schedule II: Return correct course order

BFS Topology Sort, use in-degree array.

public class Solution {    public int[] findOrder(int numCourses, int[][] prerequisites) {        Map<Integer, List<Integer>> forward = new HashMap<>();         int[] in = new int[numCourses];        ArrayList<Integer> roots = new ArrayList<>();        int[] result = new int[numCourses];        int count = numCourses-1;        //0. convert edge array into hashmap        for(int i=0; i<prerequisites.length; i++){              if(!forward.containsKey(prerequisites[i][0])){                  List<Integer> al = new ArrayList<>();                  al.add(prerequisites[i][1]);                  forward.put(prerequisites[i][0],al);              }              else{                  forward.get(prerequisites[i][0]).add(prerequisites[i][1]);              }              in[prerequisites[i][1]]++;        }          //1. find all root candidats        for(int i=0; i<numCourses; i++){            if(in[i]==0) roots.add(i);        }        //2. bfs for all roots        while(!roots.isEmpty()){            int root = roots.remove(0);            result[count] = root;            count--;            List<Integer> children = forward.get(root);            while(children!=null && !children.isEmpty()){                int child = children.remove(0);                in[child]--;                if(in[child]==0){                    roots.add(child);                    forward.remove(root);                }            }        }        for(int i=0; i<numCourses; i++){            if(in[i]>0) return new int[0];        }        return result;    }}



0 0
原创粉丝点击