1. 程式人生 > >LeetCode練習題802. Find Eventual Safe States

LeetCode練習題802. Find Eventual Safe States

題目

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.

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.

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

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.

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]
    .

思路

這道題的實質是利用深度優先演算法遍歷這個圖,然後判斷以某一點為起點時是否存在環,若不存在環,則該起點是安全的。

首先用state陣列標明每個節點的狀態,0表示未訪問過,1表示訪問過且是安全的,2訪問過且不安全。初始時,每個節點的狀態為0,即未訪問過。

然後宣告一個深度優先遍歷函式 bool oneNodePath(vector<vector<int>>& graph, int start, vector<int>& state),函式的第一個引數為原圖graph,第二個引數為遍歷起始的點,第三個引數為所有點的狀態.。

因為圖有可能不是連通圖,對每個點都需要遍歷,所以在eventualSafeNodes函式中利用for迴圈對每個點進行深度優先遍歷。如下程式碼所示:

        for (int i = 0; i < len; i++) {
            if (oneNodePath(graph, i, state)) {
                result.push_back(i);
            }
        }

在深度優先遍歷函式oneNodePath中,遍歷到的點,若它狀態為0,就將它修改為2,然後對它的子節點進行遍歷。若便利完子節點都沒發現有環,說明該節點是安全的,則修改狀態為1,否則是不安全的,保持狀態為2。

程式碼

class Solution {
public:
    bool oneNodePath(vector<vector<int>>& graph, int start, vector<int>& state) {
        if (state[start] == 0) state[start] = 2;
        else if (state[start] == 1) return true;
        else if (state[start] == 2) return false;
        for (int i = 0; i < graph[start].size(); i++) {
            if (oneNodePath(graph, graph[start][i], state) == false) return false;
        }
        state[start] = 1;
        return true;
    }
    //state代表節點狀態,0表示未訪問過,1表示訪問過且是安全的,2訪問過且不安全
    vector<int> eventualSafeNodes(vector<vector<int>>& graph) {
        int len = graph.size();
        vector<int> result;
        vector<int> state;
        //全部初始化為未訪問
        for (int i = 0; i < len; i++) {
            state.push_back(0);
        }

        for (int i = 0; i < len; i++) {
            if (oneNodePath(graph, i, state)) {
                result.push_back(i);
            }
        }
        return result;
    }
};