210. 과정 일정 II
26227 단어 cppalgorithms
설명
numCourses
에서 0
까지 총 numCourses - 1
개의 과정을 수강해야 합니다. prerequisites
배열이 제공됩니다. 여기서 prerequisites[i] = [ai, bi]
는 과정을 수강하려면 먼저 과정bi
을 수강해야 함을 나타냅니다.
ai
쌍은 [0, 1]
과정을 수강하려면 먼저 0
과정을 수강해야 함을 나타냅니다. 모든 과정을 마치기 위해 수강해야 하는 과정의 순서를 반환합니다. 유효한 답변이 많으면 그 중 하나를 반환합니다. 모든 과정을 완료할 수 없는 경우 빈 배열을 반환합니다.
예 1:
Input: numCourses = 2, prerequisites = [[1,0]]
Output: [0,1]
Explanation: There are a total of 2 courses to take. To take course 1 you should have finished course 0. So the correct course order is [0,1].
예 2:
Input: numCourses = 4, prerequisites = [[1,0],[2,0],[3,1],[3,2]]
Output: [0,2,1,3]
Explanation: There are a total of 4 courses to take. To take course 3 you should have finished both courses 1 and 2. Both courses 1 and 2 should be taken after you finished course 0.
So one correct course order is [0,1,2,3]. Another correct ordering is [0,2,1,3].
예 3:
Input: numCourses = 1, prerequisites = []
Output: [0]
제약:
1
1 <= numCourses <= 2000
0 <= prerequisites.length <= numCourses * (numCourses - 1)
prerequisites[i].length == 2
0 <= ai, bi < numCourses
ai != bi
은 구체적입니다. 솔루션
솔루션 1
직관
DFS
암호
class Solution {
private static final int WHITE = 1;
private static final int GRAY = 2;
private static final int BLACK = 3;
boolean isPossible;
Map<Integer, Integer> color;
Map<Integer, List<Integer>> adjList;
List<Integer> topologicalOrder;
private void init(int numCourses) {
isPossible = true;
color = new HashMap<>(numCourses);
adjList = new HashMap<>(numCourses);
topologicalOrder = new ArrayList<>();
// By default, all vertices are WHITE
for (int i = 0; i < numCourses; i++) {
color.put(i, WHITE);
}
}
private void dfs(int node) {
// Don't recurse further if we found a cycle already
if (!isPossible) {
return;
}
// Start the recursion
color.put(node, GRAY);
// Traverse on neighboring vertices
for (Integer neighbor : adjList.getOrDefault(node, new ArrayList<>())) {
if (color.get(neighbor) == WHITE) {
dfs(neighbor);
} else if (color.get(neighbor) == GRAY) {
// An edge to a GRAY vertex represents a cycle
isPossible = false;
}
}
// Recursion ends. We mark it as black
color.put(node, BLACK);
topologicalOrder.add(node);
}
public int[] findOrder(int numCourses, int[][] prerequisites) {
init(numCourses);
// Create the adjacency list representation of the graph
for (int[] prerequisite : prerequisites) {
int dest = prerequisite[0];
int src = prerequisite[1];
List<Integer> lst = adjList.getOrDefault(src, new ArrayList<>());
lst.add(dest);
adjList.put(src, lst);
}
// If the node is unprocessed, then call dfs on it.
for (int i = 0; i < numCourses; i++) {
if (color.get(i) == WHITE) {
dfs(i);
}
}
int[] order;
if (isPossible) {
order = new int[numCourses];
for (int i = 0; i < numCourses; i++) {
order[i] = topologicalOrder.get(numCourses - i - 1);
}
} else {
order = new int[0];
}
return order;
}
}
복잡성
class Solution {
private static final int WHITE = 1;
private static final int GRAY = 2;
private static final int BLACK = 3;
boolean isPossible;
Map<Integer, Integer> color;
Map<Integer, List<Integer>> adjList;
List<Integer> topologicalOrder;
private void init(int numCourses) {
isPossible = true;
color = new HashMap<>(numCourses);
adjList = new HashMap<>(numCourses);
topologicalOrder = new ArrayList<>();
// By default, all vertices are WHITE
for (int i = 0; i < numCourses; i++) {
color.put(i, WHITE);
}
}
private void dfs(int node) {
// Don't recurse further if we found a cycle already
if (!isPossible) {
return;
}
// Start the recursion
color.put(node, GRAY);
// Traverse on neighboring vertices
for (Integer neighbor : adjList.getOrDefault(node, new ArrayList<>())) {
if (color.get(neighbor) == WHITE) {
dfs(neighbor);
} else if (color.get(neighbor) == GRAY) {
// An edge to a GRAY vertex represents a cycle
isPossible = false;
}
}
// Recursion ends. We mark it as black
color.put(node, BLACK);
topologicalOrder.add(node);
}
public int[] findOrder(int numCourses, int[][] prerequisites) {
init(numCourses);
// Create the adjacency list representation of the graph
for (int[] prerequisite : prerequisites) {
int dest = prerequisite[0];
int src = prerequisite[1];
List<Integer> lst = adjList.getOrDefault(src, new ArrayList<>());
lst.add(dest);
adjList.put(src, lst);
}
// If the node is unprocessed, then call dfs on it.
for (int i = 0; i < numCourses; i++) {
if (color.get(i) == WHITE) {
dfs(i);
}
}
int[] order;
if (isPossible) {
order = new int[numCourses];
for (int i = 0; i < numCourses; i++) {
order[i] = topologicalOrder.get(numCourses - i - 1);
}
} else {
order = new int[0];
}
return order;
}
}
솔루션 2
직관
BFS
암호
class Solution {
public int[] findOrder(int numCourses, int[][] prerequisites) {
Map<Integer, List<Integer>> adjList = new HashMap<>();
int[] indegree = new int[numCourses];
int[] topologicalOrder = new int[numCourses];
// Create the adjacency list representation of the graph
for (int[] prerequisite : prerequisites) {
int dest = prerequisite[0];
int src = prerequisite[1];
List<Integer> lst = adjList.getOrDefault(src, new ArrayList<Integer>());
lst.add(dest);
adjList.put(src, lst);
// Record in-degree of each vertex
indegree[dest] += 1;
}
// Add all vertices with 0 in-degree to the queue
Queue<Integer> q = new LinkedList<Integer>();
for (int i = 0; i < numCourses; i++) {
if (indegree[i] == 0) {
q.add(i);
}
}
int index = 0;
// Process until the Q becomes empty
while (!q.isEmpty()) {
int node = q.remove();
topologicalOrder[index++] = node;
// Reduce the in-degree of each neighbor by 1
if (adjList.containsKey(node)) {
for (Integer neighbor : adjList.get(node)) {
indegree[neighbor]--;
// If in-degree of a neighbor becomes 0, add it to the Q
if (indegree[neighbor] == 0) {
q.add(neighbor);
}
}
}
}
// Check to see if topological sort is possible or not.
if (index == numCourses) {
return topologicalOrder;
}
return new int[0];
}
}
class Solution {
public:
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
vector<vector<int>> g(numCourses);
vector<int> in(numCourses, 0);
for (auto& p : prerequisites) {
int a = p[0], b = p[1];
// b -> a
g[b].push_back(a);
// how many prerequisites need to learn a course?
in[a] ++;
}
queue<int> q;
// in = 0, means you've already finished the prerequisites, and you can learn this course
for (int i = 0; i < numCourses; i++)
if (in[i] == 0) q.push(i);
vector<int> res;
while (!q.empty()) {
int p = q.front();
q.pop();
res.push_back(p);
for (auto& c : g[p]) {
if (--in[c] == 0) q.push(c);
}
}
if (res.size() == numCourses) return res;
else return {};
}
};
복잡성
Reference
이 문제에 관하여(210. 과정 일정 II), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/jiangwenqi/210-course-schedule-ii-10ml텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)