问题描述
有一个有 n
个节点的有向图,节点按 0
到 n - 1
编号。图由一个 索引从 0 开始 的 2D
整数数组 graph
表示, graph[i]
是与节点 i
相邻的节点的整数数组,这意味着从节点 i
到 graph[i]
中的每个节点都有一条边。
如果一个节点没有连出的有向边,则它是 终端节点 。如果没有出边,则节点为终端节点。如果从该节点开始的所有可能路径都通向 终端节点 ,则该节点为 安全节点 。
返回一个由图中所有 安全节点 组成的数组作为答案。答案数组中的元素应当按 升序 排列。
示例 1:
输入:graph = [[1,2],[2,3],[5],[0],[5],[],[]]
输出:[2,4,5,6]
解释:示意图如上。
节点 5 和节点 6 是终端节点,因为它们都没有出边。
从节点 2、4、5 和 6 开始的所有路径都指向节点 5 或 6 。
示例 2:
输入:graph = [[1,2,3,4],[1,2],[3,4],[0,4],[]]
输出:[4]
解释:
只有节点 4 是终端节点,从节点 4 开始的所有路径都通向节点 4 。
提示:
n == graph.length
1 <= n <= 10⁴
0 <= graph[i].length <= n
0 <= graph[i][j] <= n - 1
graph[i]
按严格递增顺序排列。- 图中可能包含自环。
解题思路
典型的拓扑排序题,但一般的拓扑排序是考虑节点的入度,这里我们需要改为考虑节点的出度,对应的res
即为所求。
代码
class Solution {
public:
vector<int> eventualSafeNodes(vector<vector<int>>& graph) {
// 拓扑排序,bfs
int n = graph.size();
vector<int> in_arr(n);
for (int i = 0; i < n; ++i) {
for (int v : graph[i]) {
in_arr[v]++;
}
}
std::queue<int> in0;
for (int i = 0; i < n; ++i) {
// 将入度为0的点放入in0
if (in_arr[i] == 0) {
in0.push(i);
}
}
vector<int> res;
while (!in0.empty()) {
int idx = in0.front();
// 从in0中取一个点放入res
res.push_back(idx);
in0.pop();
for (auto v : graph[idx]) {
if (--in_arr[v] == 0) {
in0.push(v);
}
}
}
return res;
}
};
标签:Medium,找到,graph,in0,int,vector,res,802,节点
From: https://www.cnblogs.com/zwyyy456/p/17478036.html