1、第一次看到题目,回溯/动态都想了一下,发现都行不通,看了大神讲解后说是属于有向图判断是否存在环,当时感觉一阵头大,果断跳过,现在再回来看题目理清思路感觉没有那么难了。虽然图的结构比较复杂,但题目本身不是很复杂。看的讲解分为BFS与DFS两种解法,先试试BFS了。其实整体的思路关键在于,想要学完所有课程,要求对应的有向图中不能存在环。
维护以下数据结构:graph [][]int(存储有向图信息)inDegree []int(记录各个节点的入度)queue []int(队列,存储当前入度为0的节点,节点前面所需的节点均已在拓扑中)
过程:根据 prerequisites,在graph[i]中存储节点i所指向的节点。同时计算各个节点所对应的入度,将入度为0的点加入到queue中。
之后遍历queue,针对队列队首的节点i,遍历图中该节点指向的节点graph[i],对应节点的入度值--(所需的先修节点--),如果节点入度值减为0,说明当前节点前面所需的节点均已在拓扑中,将其加入队列中。
最后遍历inDegree,如果存在节点入度不为0,说明存在没有放入拓扑的节点,返回false,否则true。实现代码如下:
func canFinish(numCourses int, prerequisites [][]int) bool {
// 构建图结构
var graph [][]int=make([][]int, numCourses)
// 记录各节点入度
var inDegree []int=make([]int, numCourses)
for _, v:=range prerequisites{
graph[v[1]]=append(graph[v[1]], v[0]+1)
inDegree[v[0]]++
}
// 记录入度为0的点
var queue []int
for k, v:=range inDegree{
if v==0 { queue=append(queue, k) }
}
for len(queue)>0{
node:=queue[0]
queue=queue[1:]
for _, v:=range graph[node]{
inDegree[v-1]--
if inDegree[v-1]==0{ queue=append(queue, v-1) }
}
}
for _, v:=range inDegree{ if v!=0{ return false } }
return true
}