2192. 有向无环图中一个节点的所有祖先

132 阅读1分钟

题目:
给你一个正整数 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
}