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++;
}
}