LeetCode //C - 210. Course Schedule II

210. Course Schedule II

There are a total of numCourses courses you have to take, labeled from 0 to numCourses - 1. You are given an array prerequisites where prerequisites[i] = [ai, bi] indicates that you must take course bi first if you want to take course ai.

  • For example, the pair [0, 1], indicates that to take course 0 you have to first take course 1.

Return the ordering of courses you should take to finish all courses. If there are many valid answers, return any of them. If it is impossible to finish all courses, return an empty array.
 

Example 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].

Example 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].

Example 3:

Input: numCourses = 1, prerequisites = []
Output: [0]

Constraints:
  • 1 <= numCourses <= 2000
  • 0 <= prerequisites.length <= numCourses * (numCourses - 1)
  • prerequisites[i].length == 2
  • 0 <= a i , b i a_i, b_i ai,bi < numCourses
  • a i ! = b i a_i != b_i ai!=bi
  • All the pairs [ a i , b i a_i, b_i ai,bi] are distinct.

From: LeetCode
Link: 210. Course Schedule II


Solution:

Ideas:

1. Represent the Courses as a Directed Graph:

  • Courses are represented as nodes in the graph.
  • The prerequisites are represented as directed edges in the graph, where an edge from course u to course v means v is a prerequisite for u.

2. Calculate In-degree for each Course:

  • The in-degree of a node in a directed graph is the number of edges coming into it.
  • For every course, calculate its in-degree, i.e., the number of courses that have it as a prerequisite.

3. Perform Topological Sort:

  • Initialize a queue and add all courses with in-degree 0 to it.
  • For each course u dequeued from the queue:
    • Add it to the result array.
    • For each course v adjacent to u, decrement the in-degree of v.
    • If the in-degree of v becomes 0, enqueue v.
  • If the size of the result array is equal to the number of courses, return the result array, else return an empty array.
Code:
/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
int* findOrder(int numCourses, int** prerequisites, int prerequisitesSize, int* prerequisitesColSize, int* returnSize) {
    
    
    int *result = (int *)malloc(numCourses * sizeof(int));
    if(!result) return NULL; // Return NULL if memory allocation fails
    
    int *inDegree = (int *)calloc(numCourses, sizeof(int));
    if(!inDegree) {
    
    
        free(result);
        return NULL;
    }
    
    int **adjList = (int **)malloc(numCourses * sizeof(int *));
    if(!adjList) {
    
    
        free(result);
        free(inDegree);
        return NULL;
    }
    
    for(int i = 0; i < numCourses; i++) {
    
    
        adjList[i] = (int *)malloc(numCourses * sizeof(int));
        if(!adjList[i]) {
    
    
            for(int j = 0; j < i; j++)
                free(adjList[j]);
            free(adjList);
            free(inDegree);
            free(result);
            return NULL;
        }
        for(int j = 0; j < numCourses; j++)
            adjList[i][j] = 0;
    }
    
    for(int i = 0; i < prerequisitesSize; i++) {
    
    
        int course = prerequisites[i][0];
        int prereq = prerequisites[i][1];
        adjList[prereq][course] = 1; // prereq -> course
        inDegree[course]++;
    }
    
    int *queue = (int *)malloc(numCourses * sizeof(int));
    if(!queue) {
    
    
        for(int i = 0; i < numCourses; i++)
            free(adjList[i]);
        free(adjList);
        free(inDegree);
        free(result);
        return NULL;
    }
    
    int front = 0, rear = 0;
    
    for(int i = 0; i < numCourses; i++)
        if(inDegree[i] == 0)
            queue[rear++] = i;
    
    int count = 0;
    while(front < rear) {
    
    
        int v = queue[front++];
        result[count++] = v;
        for(int i = 0; i < numCourses; i++) {
    
    
            if(adjList[v][i]) {
    
    
                inDegree[i]--;
                if(inDegree[i] == 0)
                    queue[rear++] = i;
            }
        }
    }
    
    *returnSize = (count == numCourses) ? count : 0;
    
    for(int i = 0; i < numCourses; i++)
        free(adjList[i]);
    free(adjList);
    free(inDegree);
    free(queue);
    
    if(count < numCourses) {
    
    
        free(result);
        return NULL;
    }
    
    return result;
}

猜你喜欢

转载自blog.csdn.net/navicheung/article/details/133312965