[Swift]LeetCode802. 找到最終的安全狀態 | Find Eventual Safe States

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址: http://www.javashuo.com/article/p-spiqmywz-me.html 
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html

In a directed graph, we start at some node and every turn, walk along a directed edge of the graph.  If we reach a node that is terminal (that is, it has no outgoing directed edges), we stop.node

Now, say our starting node is eventually safe if and only if we must eventually walk to a terminal node.  More specifically, there exists a natural number K so that for any choice of where to walk, we must have stopped at a terminal node in less than K steps.git

Which nodes are eventually safe?  Return them as an array in sorted order.github

The directed graph has N nodes with labels 0, 1, ..., N-1, where N is the length of graph.  The graph is given in the following form: graph[i] is a list of labels j such that (i, j) is a directed edge of the graph.數組

Example:
Input: graph = [[1,2],[2,3],[5],[0],[5],[],[]]
Output: [2,4,5,6]
Here is a diagram of the above graph.

Illustration of graph

Note:安全

  • graph will have length at most 10000.
  • The number of edges in the graph will not exceed 32000.
  • Each graph[i] will be a sorted list of different integers, chosen within the range [0, graph.length - 1].

在有向圖中, 咱們從某個節點和每一個轉向處開始, 沿着圖的有向邊走。 若是咱們到達的節點是終點 (即它沒有連出的有向邊), 咱們中止。微信

如今, 若是咱們最後能走到終點,那麼咱們的起始節點是最終安全的。 更具體地說, 存在一個天然數 K,  不管選擇從哪裏開始行走, 咱們走了不到 K 步後必能中止在一個終點。app

哪些節點最終是安全的? 結果返回一個有序的數組。less

該有向圖有 N 個節點,標籤爲 0, 1, ..., N-1, 其中 N是 graph 的節點數.  圖以如下的形式給出: graph[i] 是節點 j 的一個列表,知足 (i, j) 是圖的一條有向邊。spa

示例:
輸入:graph = [[1,2],[2,3],[5],[0],[5],[],[]]
輸出:[2,4,5,6]
這裏是上圖的示意圖。

Illustration of graph

提示:

  • graph 節點數不超過 10000.
  • 圖的邊數不會超過 32000.
  • 每一個 graph[i] 被排序爲不一樣的整數列表, 在區間 [0, graph.length - 1] 中選取。

Runtime: 796 ms
Memory Usage: 19.7 MB
 1 class Solution {
 2     func eventualSafeNodes(_ graph: [[Int]]) -> [Int] {
 3         var graph = graph
 4         var n:Int = graph.count
 5         // 0 white, 1 gray, 2 black
 6         var res:[Int] = [Int]()
 7         var color:[Int] = [Int](repeating:0,count:n)
 8         for i in 0..<n
 9         {
10             if helper(&graph, i, &color)
11             {
12                 res.append(i)
13             }
14         }
15         return res
16     }
17     
18     func helper(_ graph:inout [[Int]],_ cur:Int,_ color:inout [Int]) -> Bool
19     {
20         if color[cur] > 0
21         {
22             return color[cur] == 2
23         }
24         color[cur] = 1
25         for i in graph[cur]
26         {
27             if color[i] == 2 {continue}
28             if color[i] == 1 || !helper(&graph, i, &color)
29             {
30                 return false
31             }
32         }
33         color[cur] = 2
34         return true
35     }
36 }

1116ms

 1 class Solution {
 2     func eventualSafeNodes(_ graph: [[Int]]) -> [Int] {
 3         var values: [Int?] = Array(repeatElement(nil, count: graph.count))
 4         for nodes in graph.enumerated() {
 5             dfs(graph, nodes.offset, &values)
 6         }
 7         return values.enumerated().filter{$0.element == 1}.map{$0.offset}
 8     }
 9     
10     // nil = not visited
11     // 1 = safe
12     // 2 = cycle/visited
13     func dfs(_ graph: [[Int]], _ node: Int, _ values : inout [Int?]) -> Bool {
14         if values[node] == 2 {return false}
15         if values[node] == 1 {return true}
16         values[node] = 2
17         for neighbor in graph[node] {
18             if !dfs(graph, neighbor, &values) {
19                 values[node] = 2
20                 return false
21             }
22         }
23         values[node] = 1
24         return true
25     }
26 }

1156ms

 1 class Solution {
 2     func eventualSafeNodes(_ graph: [[Int]]) -> [Int] {
 3         var outDegree = graph.map { $0.count }
 4         var safeVertices = outDegree.enumerated().compactMap { $0.1 == 0 ? $0.0 : nil }
 5         var adj = [Int: [Int]]()
 6         for (u, edges) in graph.enumerated() {
 7             for v in edges {
 8                 adj[v, default: []].append(u)
 9             }
10         }
11 
12         var result = [Int]()
13         var i = 0
14         while i < safeVertices.count {
15             result.append(safeVertices[i])
16             for v in adj[safeVertices[i], default: []] {
17                 outDegree[v] -= 1
18                 if outDegree[v] == 0 {
19                     safeVertices.append(v)
20                 }
21             }
22             i += 1
23         }
24         return result.sorted(by: <)
25     }
26 }
相關文章
相關標籤/搜索