图——20191220

3 Leetcode207.课程表
3.1题目描述
现在你总共有 n 门课需要选,记为 0 到 n-1。
在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们: [0,1]
给定课程总量以及它们的先决条件,判断是否可能完成所有课程的学习?

示例 1:
输入: 2, [[1,0]]
输出: true
解释: 总共有 2 门课程。学习课程 1 之前,你需要完成课程 0。所以这是可能的。

示例 2:
输入: 2, [[1,0],[0,1]]
输出: false
解释: 总共有 2 门课程。学习课程 1 之前,你需要先完成课程 0;并且学习课程 0 之前,你还应先完成课程 1。这是不可能的。

说明:
输入的先决条件是由边缘列表表示的图形,而不是邻接矩阵。详情请参见图的表示法。
你可以假定输入的先决条件中没有重复的边。

提示:
这个问题相当于查找一个循环是否存在于有向图中。如果存在循环,则不存在拓扑排序,因此不可能选取所有课程进行学习。
通过 DFS 进行拓扑排序 - 一个关于Coursera的精彩视频教程(21分钟),介绍拓扑排序的基本概念。
拓扑排序也可以通过 BFS 完成。

3.2分析
有向图中是否有循环,使用邻接矩阵存储图,深度优先遍历图。
节点的状态包括:0 未访问;1 当前已经访问,被其他节点启动的DFS访问;-1 其他路径已经访问,已被其他节点启动的DFS访问。

1.5 3.3代码
//false表示不可以,true表示可以
bool dfsGraph(int numCourses, int** matrix, int* visit, int pos) {
if(visit[pos] == 1) {
return false;
}
if(visit[pos] == -1) {
return true;
}
visit[pos] = 1;
int i = 0, j = 0;

for(i = 0; i < numCourses; i++) {
    if(i != pos && matrix[pos][i] == 1) {
        if(!dfsGraph(numCourses, matrix, visit, i)) {
            return false;
        }
    }

}
//本次节点访问完毕,置为-1
visit[pos] = -1;
return true;
}

void destryMatrix(int** matrix, int numCourses) {
int i = 0;
if(matrix != NULL) {
for(i = 0; i < numCourses; i++) {
if(matrix[i] != NULL) {
free(matrix[i]);
matrix[i] = NULL;
}
}

    free(matrix);
    matrix = NULL;
}

}

bool canFinish(int numCourses, int** prerequisites, int prerequisitesSize, int* prerequisitesColSize){
int i = 0, j = 0;
bool result = true;
//初始化图的邻接矩阵
int** matrix = (int**)malloc(sizeof(int*) * numCourses);
if(matrix == NULL) {
return false;
}
for(i = 0; i < numCourses; i++) {
matrix[i] = (int*)malloc(sizeof(int) * numCourses);
if(matrix[i] == NULL) {
return false;
}

    for(j = 0; j < numCourses; j++) {
        matrix[i][j] = 0;
    }
}

for(i= 0; i < prerequisitesSize; i++) {
    if(prerequisites[i][0] == prerequisites[i][1]) {
        destryMatrix(matrix, numCourses);
        return false;
    }

    matrix[prerequisites[i][0]][prerequisites[i][1]] = 1;
}

//初始化visit
int* visit = (int*)malloc(sizeof(int) * numCourses);
if(visit == NULL) {
    destryMatrix(matrix, numCourses);
    return false;
}
for(i = 0; i < numCourses; i++) {
    visit[i] = 0;
}

//深度优先遍历
for(i = 0; i < numCourses; i++) {
    if(!dfsGraph(numCourses, matrix, visit, i)) {
        result = false;
        break;
    }
}

destryMatrix(matrix, numCourses);
free(visit);
visit = NULL;

return result;

}

发布了39 篇原创文章 · 获赞 1 · 访问量 856

猜你喜欢

转载自blog.csdn.net/weixin_42268479/article/details/103635759