You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

114 lines
2.6 KiB

2 years ago
package class33;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
public class Problem_0207_CourseSchedule {
// 一个node就是一个课程
// name是课程的编号
// in是课程的入度
public static class Course {
public int name;
public int in;
public ArrayList<Course> nexts;
public Course(int n) {
name = n;
in = 0;
nexts = new ArrayList<>();
}
}
public static boolean canFinish1(int numCourses, int[][] prerequisites) {
if (prerequisites == null || prerequisites.length == 0) {
return true;
}
// 一个编号 对应 一个课的实例
HashMap<Integer, Course> nodes = new HashMap<>();
for (int[] arr : prerequisites) {
int to = arr[0];
int from = arr[1]; // from -> to
if (!nodes.containsKey(to)) {
nodes.put(to, new Course(to));
}
if (!nodes.containsKey(from)) {
nodes.put(from, new Course(from));
}
Course t = nodes.get(to);
Course f = nodes.get(from);
f.nexts.add(t);
t.in++;
}
int needPrerequisiteNums = nodes.size();
Queue<Course> zeroInQueue = new LinkedList<>();
for (Course node : nodes.values()) {
if (node.in == 0) {
zeroInQueue.add(node);
}
}
int count = 0;
while (!zeroInQueue.isEmpty()) {
Course cur = zeroInQueue.poll();
count++;
for (Course next : cur.nexts) {
if (--next.in == 0) {
zeroInQueue.add(next);
}
}
}
return count == needPrerequisiteNums;
}
// 和方法1算法过程一样
// 但是写法优化了
public static boolean canFinish2(int courses, int[][] relation) {
if (relation == null || relation.length == 0) {
return true;
}
// 3 : 0 1 2
// nexts : 0 {}
// 1 {}
// 2 {}
// 3 {0,1,2}
ArrayList<ArrayList<Integer>> nexts = new ArrayList<>();
for (int i = 0; i < courses; i++) {
nexts.add(new ArrayList<>());
}
// 3 入度 1 in[3] == 1
int[] in = new int[courses];
for (int[] arr : relation) {
// arr[1] from arr[0] to
nexts.get(arr[1]).add(arr[0]);
in[arr[0]]++;
}
// 队列
int[] zero = new int[courses];
// 该队列有效范围是[l,r)
// 新来的数放哪r位置r++
// 出队列的数从哪拿l位置l++
// l == r 队列无元素 l < r 队列有元素
int l = 0;
int r = 0;
for (int i = 0; i < courses; i++) {
if (in[i] == 0) {
zero[r++] = i;
}
}
int count = 0;
while (l != r) {
count++; // zero[l] 出队列 l++
for (int next : nexts.get(zero[l++])) {
if (--in[next] == 0) {
zero[r++] = next;
}
}
}
return count == nexts.size();
}
}