玩命加载中 . . .

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


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

给你一个正整数 n ,它表示一个 有向无环图 中节点的数目,节点编号为 0n - 1 (包括两者)。

给你一个二维整数数组 edges ,其中 edges[i] = [fromi, toi] 表示图中一条从 fromitoi 的单向边。

请你返回一个数组 answer,其中 answer[i] 是第 i 个节点的所有 祖先 ,这些祖先节点 升序 排序。

如果 u 通过一系列边,能够到达 v ,那么我们称节点 u 是节点 v 的 祖先 节点。

示例 1:

输入:n = 8, edgeList = [[0,3],[0,4],[1,3],[2,4],[2,7],[3,5],[3,6],[3,7],[4,6]]
输出:[[],[],[],[0,1],[0,2],[0,1,3],[0,1,2,3,4],[0,1,2,3]]
解释:
上图为输入所对应的图。
- 节点 012 没有任何祖先。
- 节点 32 个祖先 01- 节点 42 个祖先 02- 节点 53 个祖先 013- 节点 65 个祖先 01234- 节点 74 个祖先 0123

method: 拓扑排序

vector<vector<int>> getAncestors(int n, vector<vector<int>>& edges) {
    vector<unordered_set<int>> anc(n);  // set去重
    vector<vector<int>> e(n);
    vector<int> indegree(n);
    for (auto& t : edges) {
        e[t[0]].push_back(t[1]);    // t[0] -> t[1]
        indegree[t[1]]++;
    }
    queue<int> q;
    for (int i = 0; i < n; i++) {
        if (indegree[i] == 0) q.push(i);
    }
    while (!q.empty()) {
        int x = q.front();
        q.pop();
        for (auto& v : e[x]) {
            anc[v].insert(x);   // 当前节点成为其后继节点的祖先
            for (auto t : anc[x]) {
                anc[v].insert(t);   // 当前节点的祖先也是其后继节点的祖先
            }
            if (--indegree[v] == 0) q.push(v);
        }
    }
    vector<vector<int>> res;
    for (int i = 0; i < n; i++) {
        vector<int> vec;
        for (auto t : anc[i]) vec.push_back(t);
        sort(vec.begin(), vec.end());
        res.push_back(vec);
    }
    return res;
}

文章作者: kunpeng
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 kunpeng !
  目录