LeetCode Graph:M207

xiaoxiao2021-02-27  284

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.You may assume that there are no duplicate edges in the input prerequisites.

click to show more hints.

package com.graph; import java.util.LinkedList; import java.util.Queue; import java.util.Stack; public class M207_Course_Schedule { int n; int[][] pre; int[] visited; int m; //方法一:根据图的DFS策略,如果遍历过程中发现环,则不能修完所有课 //递归 //TC=O(m^n) public boolean canFinish_rec(int numCourses, int[][] prerequisites) { n = numCourses; pre = prerequisites; if(n==0 || n==1) return true; if(pre==null || pre.length<1) return true; visited = new int[n]; m = pre.length; boolean flag = true; for(int i=0; i<n; i++) { if(visited[i]==0) { visited[i] = 1; flag = DFS(i); visited[i] = 2; if(!flag) return false; } } return flag; } boolean DFS(int v) { boolean flag = true; for(int i=0; i<m; i++) {//遍历边的时候,可以优化,将已经访问过的边标记 int a = pre[i][0]; int b = pre[i][1]; if(b==v) { //到这里,说明b是访问过的 if(visited[a]==0) { visited[a]=1; flag = DFS(a); visited[a]=2; if(!flag) return false; }else if(visited[a]==1) return false; } } return flag; } //迭代 //TC=O(m^n) public boolean canFinish_it(int numCourses, int[][] prerequisites) { n = numCourses; pre = prerequisites; if(n==0 || n==1) return true; if(pre==null || pre.length<1) return true; visited = new int[n]; m = pre.length; Stack<Integer> stack = new Stack<Integer>(); for(int i=0; i<n; i++) { if(visited[i]==0) { stack.push(i); visited[i] = 1; } int v; while(!stack.isEmpty()) { v = stack.peek();//revise int j=0; int flag=0; for(; j<m; j++) {//遍历边的时候,可以优化,将已经访问过的边标记 int a = pre[j][0]; int b = pre[j][1]; if(v==b) { if(visited[a]==0) { flag=1; stack.push(a); visited[a]=1; break; }else if(visited[a]==1) return false; } } //revise if(flag==0) { v = stack.pop(); visited[v] = 2; } } } return true; } //方法二:根据拓扑排序,实质为BFS策略 public boolean canFinish_1(int numCourses, int[][] prerequisites) { //空间换时间 n = numCourses; pre = prerequisites; m = pre.length; int[] nums = new int[n]; for(int i=0; i<m; i++) { nums[pre[i][1]]++; } Queue<Integer> q = new LinkedList<Integer>(); int count=0; for(int i=0; i<n; i++) { if(nums[i]==0) { q.add(i); count++; } } while(!q.isEmpty()) { int t = q.poll(); for(int i=0; i<m; i++) { if(t==pre[i][0]) { int k = pre[i][1]; nums[k]--; if(nums[k]==0) { q.add(k); count++; } } } } return count==n; } public static void main(String[] args) { M207_Course_Schedule m = new M207_Course_Schedule(); m.canFinish_it(3, new int[][] {{1,0},{2,0},{0,2}}); } }

转载请注明原文地址: https://www.6miu.com/read-11602.html

最新回复(0)