1. 程式人生 > 實用技巧 >LeetCode 802. 找到最終的安全狀態

LeetCode 802. 找到最終的安全狀態

題目描述

在有向圖中, 我們從某個節點和每個轉向處開始, 沿著圖的有向邊走。 如果我們到達的節點是終點 (即它沒有連出的有向邊), 我們停止。
現在, 如果我們最後能走到終點,那麼我們的起始節點是最終安全的。 更具體地說, 存在一個自然數 \(K\), 無論選擇從哪裡開始行走, 我們走了不到 \(K\) 步後必能停止在一個終點。

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

該有向圖有 N 個節點,標籤為 0, 1, ..., N-1, 其中 Ngraph的節點數. 圖以以下的形式給出: 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

思路解析

  1. 定義安全節點:
    沒有出邊的節點均為安全節點;
    出邊連線的節點均為安全節點的節點。
  2. 查詢圖的最終安全節點(沒有出邊的節點)
  3. 將圖反向,得到rGraph,依次查詢僅與安全節點相連的節點,並存入佇列

程式碼實現

class Solution {
public:
    vector<int> eventualSafeNodes(vector<vector<int>>& graph) {
        // Find terminate
        vector<int> terminates;
        vector<int> degree;
        for(int i = 0; i < graph.size(); i++) {
            if(graph[i].empty())
                terminates.push_back(i);
            degree.push_back(graph[i].size());
        }
        // Reverse graph
        vector<vector<int>> rGraph = reverseGraph(graph);
        // Construct queue
        queue<int> safeNodes;
        for(auto node : terminates)
            safeNodes.push(node);
        while(!safeNodes.empty()) {
            int curNode = safeNodes.front();
            for(auto pNode : rGraph[curNode]) {
                for(auto tNode : graph[pNode]) {
                    if(tNode == curNode) {
                        degree[pNode]--;
                        break;
                    }
                }
                if(degree[pNode] <= 0) {
                    safeNodes.push(pNode);
                    terminates.push_back(pNode);
                }
                /*
                for(auto nt = graph[pNode].begin(); nt != graph[pNode].end(); nt++) {
                    if((*nt) == curNode)
                        graph[pNode].erase(nt);
                    if(nt == graph[pNode].end())
                        break;
                }
                if(graph[pNode].empty()) {
                    safeNodes.push(pNode);
                    terminates.push_back(pNode);
                }
                */
            }
            safeNodes.pop();
        }
        sort(terminates.begin(), terminates.end());
        return terminates;
    }

    vector<vector<int>> reverseGraph(vector<vector<int>> graph) {
        vector<vector<int>> rGraph(graph.size(), vector<int>{});
        for(int i = 0; i < graph.size(); i++)
            for(auto tNode : graph[i])
                rGraph[tNode].push_back(i);
        return rGraph;
    }
};