力扣207
力扣210
力扣1203
求出一种拓扑排序方法的最优时间复杂度为 O(n+m),其中 n 和 m 分别是有向图 G 的节点数和边数
图的几种表示方法
List<List<Integer>> edges;//边
int[] visited;//0-未搜索,1-搜索中,2-已完成搜索
boolean valid = true;
int[] indeg;//入度
207:DFS
public boolean canFinish(int numCourses, int[][] prerequisites) {
edges = new ArrayList<List<Integer>>();
for(int i=0;i<numCourses;i++) {
edges.add(new ArrayList<Integer>());
}
visited = new int[numCourses];
for(int[] info:prerequisites) {
edges.get(info[1]).add(info[0]);
}
for(int i=0;i<numCourses && valid;i++) {
if(visited[i]==0) {
dfs(i);
}
}
return valid;
}
public void dfs(int u) {
visited[u]=1;
for(int v:edges.get(u)) {
if(visited[v]==0) {
dfs(v);
if(!valid)return;
}else if(visited[v]==1) {
valid = false;
return;
}
}
visited[u]=2;
}
207:BFS
public boolean canFinish_1(int numCourses, int[][] prerequisites) {
edges = new ArrayList<List<Integer>>();//边
for(int i=0;i<numCourses;i++) {
edges.add(new ArrayList<Integer>());
}
indeg = new int[numCourses];//入度
for(int[] info:prerequisites) {
edges.get(info[1]).add(info[0]);
indeg[info[0]]++;
}
Queue<Integer> queue = new LinkedList<Integer>();
for(int i=0;i<numCourses;i++) {
if(indeg[i]==0) {
queue.offer(i);
}
}
int visited = 0;
while(!queue.isEmpty()) {
visited++;
int u = queue.poll();
for(int v:edges.get(u)) {
indeg[v]--;
if(indeg[v]==0) {
queue.offer(v);
}
}
}
return visited == numCourses;
}