1. 题目描述
你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。
在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程 bi 。
例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。
请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。
示例 1:
输入:numCourses = 2, prerequisites = [[1,0]]
输出:true
解释:总共有 2 门课程。学习课程 1 之前,你需要完成课程 0 。这是可能的。
示例 2:
输入:numCourses = 2, prerequisites = [[1,0],[0,1]]
输出:false
解释:总共有 2 门课程。学习课程 1 之前,你需要先完成课程 0 ;并且学习课程 0 之前,你还应先完成课程 1 。这是不可能的。
提示:
1 <= numCourses <= 105
0 <= prerequisites.length <= 5000
prerequisites[i].length == 2
0 <= ai, bi < numCourses
prerequisites[i] 中的所有课程对 互不相同
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/course-schedule
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
2.代码如下
typedef struct st_Queue
{
int array[2000];
int head;
int tail;
int size;
}Queue;
#if 0
使用队列,动态地维护了结点的出入队动作代表的遍历与否。
#endif
void enqueue(Queue *queue,int val)
{
queue->array[queue->tail] = val;
queue->tail += 1;
queue->size += 1;
}
int dequeue(Queue *queue)
{
int tmp = queue->array[queue->head];
queue->head += 1;
queue->size -= 1;
return tmp;
}
void que_init(Queue *queue)
{
memset(queue,0,sizeof(Queue));
}
bool canFinish(int numCourses, int** prerequisites, int prerequisitesSize, int* prerequisitesColSize){
int i = 0,j = 0;
int *degree = NULL;
int **map = NULL;
int *res = NULL;
int tmpval = 0;
int cnt = 0;
Queue g_queue;
que_init(&g_queue);
degree = (int *)malloc(sizeof(int)*numCourses);
memset(degree,0,sizeof(int)*numCourses);
map = (int **)malloc(sizeof(int *)*numCourses);
memset(map,0,sizeof(int *)*numCourses);
for (i = 0;i < numCourses;i++)
{
map[i] = (int *)malloc(sizeof(int)*numCourses);
memset(map[i],0,sizeof(int)*numCourses);
}
for (j = 0; j < prerequisitesSize;j++)//使用degree记录每个课程的出入度
{
degree[prerequisites[j][0]] += 1;//入度
map[prerequisites[j][1]][prerequisites[j][0]] = 1;
}
for (j=0;j<numCourses;j++)
{
if (degree[j] == 0)
{
enqueue(&g_queue,j);
}
}
while (g_queue.size != 0)
{
tmpval = dequeue(&g_queue);
cnt++;
for (i = 0 ;i < numCourses;i++)
{
if (map[tmpval][i] == 1)//找到节点
{
degree[i] -= 1;//入度-1
if (degree[i] == 0)//如果入度为0,则入队
{
enqueue(&g_queue,i);
}
}
}
}
for (i = 0;i < numCourses;i++)
{
free(map[i]);
}
free(map);
free(degree);
if (cnt != numCourses)
{
return false;
}
return true;
}