LeetCode 802. 找到最终的安全状态
题目
在有向图中, 我们从某个节点和每个转向处开始, 沿着图的有向边走。 如果我们到达的节点是终点 (即它没有连出的有向边), 我们停止。
现在, 如果我们最后能走到终点,那么我们的起始节点是最终安全的。 更具体地说, 存在一个自然数 K, 无论选择从哪里开始行走, 我们走了不到 K 步后必能停止在一个终点。
哪些节点最终是安全的? 结果返回一个有序的数组。
该有向图有 N 个节点,标签为 0, 1, ..., N-1, 其中 N 是 graph 的节点数. 图以以下的形式给出: graph[i] 是节点 j 的一个列表,满足 (i, j) 是图的一条有向边。
示例:
输入:graph = [[1,2],[2,3],[5],[0],[5],[],[]]
输出:[2,4,5,6]
这里是上图的示意图。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-eventual-safe-states
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
topsort,没有反过来搜,没有入度的就是安全的
代码
class Solution {
static int V;
static int EdgeCount = 0;
static edge[] edges;
static int head[];
static int[] degree;
static class edge {
int from, to, next;
public edge(int from, int to, int next) {
this.from = from;
this.to = to;
this.next = next;
}
}
public static List<Integer> eventualSafeNodes(int[][] graph) {
edges = new edge[32000];
head = new int[graph.length];
V = graph.length;
EdgeCount = 0;
degree = new int[V];
for (int i = 0; i < V; i++)
head[i] = -1;
for (int i = 0; i < graph.length; i++) {
for (int k = 0; k < graph[i].length; k++) {
addEdge(graph[i][k], i);
degree[i]++;
}
}
return bfs();
}
public static List<Integer> bfs() {
boolean[] isOkay = new boolean[V];
Queue<Integer> q = new LinkedList<Integer>();
for (int i = 0; i < V; i++) {
if (degree[i] == 0)
q.offer(i);
}
while (!q.isEmpty()) {
int k = q.poll();
isOkay[k] = true;
for (int nextEdge = head[k]; nextEdge != -1; nextEdge = edges[nextEdge].next) {
edge tmp = edges[nextEdge];
degree[tmp.to]--;
if ((degree[tmp.to]) == 0) {
q.offer(tmp.to);
}
}
}
ArrayList<Integer> re = new ArrayList<Integer>();
for (int i = 0; i < isOkay.length; i++) {
if (isOkay[i] == true) {
re.add(i);
}
}
return re;
}
public static void addEdge(int from, int to) {
edges[EdgeCount] = new edge(from, to, head[from]);
head[from] = EdgeCount++;
}
}