[力扣c语言实现]207. 课程表(拓扑排序)

207. 课程表(拓扑排序)

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
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

扫描二维码关注公众号,回复: 13128590 查看本文章

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;
}

猜你喜欢

转载自blog.csdn.net/dengwodaer/article/details/114295708