题目:
给你一个正整数 n ,它表示一个 有向无环图 中节点的数目,节点编号为 0 到 n - 1 (包括两者)。
给你一个二维整数数组 edges ,其中 edges[i] = [fromi, toi] 表示图中一条从 fromi 到 toi 的单向边。
请你返回一个数组 answer,其中 **answer[i]是第 i 个节点的所有 祖先 ,这些祖先节点 升序 排序。
如果 u 通过一系列边,能够到达 v ,那么我们称节点 u 是节点 v 的 祖先 节点。
算法:
方法一:拓补排序
func getAncestors(n int, edges [][]int) [][]int {
ans := make([][]int, n)
anc := make([]map[int]bool, n)
inDegree := make([]int, n)
g := make([][]int, n)
// 1. 计算邻接表和入度数组
for i := range edges {
g[edges[i][0]] = append(g[edges[i][0]], edges[i][1])
inDegree[edges[i][1]] ++
}
queue := make([]int, 0 )
// 2. 将入度为0的节点加入quque,queue中保存入度为0的节点,它们可能是别的节点的祖先
for i := 0; i < n; i ++ {
if inDegree[i] == 0 {
queue = append(queue, i)
}
}
for len(queue) != 0 {
u := queue[0]
queue = queue[1:]
// 3. 取出节点u
for _, v := range g[u] {
if anc[v] == nil {
anc[v] = make(map[int]bool)
}
// 4. 将u,以及u的父节点设置为,v节点的父节点,需要去重
anc[v][u] = true
for a := range anc[u] {
anc[v][a] = true
}
// 5. 将v的入度减一,如果入度为0,则加入队列
inDegree[v] --
if inDegree[v] == 0 {
queue = append(queue, v)
}
}
}
for i := range anc {
if anc[i] != nil {
for key := range anc[i] {
ans[i] = append(ans[i], key)
}
sort.Ints(ans[i])
}
}
return ans
}