Week5

Week5

Graph
question source: Find Eventual Safe States

question description

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

这是一道关于图的题目,如果一个点在有限步内一定能到达终点,那么它就是安全的,题目要求我们找出所有安全的点。理解题意很重要,想一想,如果一个点在一个环上的话,它可以一直在环上走,而不能在有限步到达终点,所以说,这实际上是要我们判断图是否存在有环。

解决方法

使用DFS遍历,如果遍历了这个点,发现这个点,或者这个点的子孙结点有环,那就不能在有限步内到达终点。判断是否有环,就是用DFS,倘若遍历到一个已经访问过的结点,则说明构成环,那么该结点就是不安全的。DFS要用一个visited数组来标记是否访问,现在改成用一个color数组来实现,0代表没访问,1代表是安全的,2代表不安全。

实现代码如下

class Solution {
public:
    vector<int> eventualSafeNodes(vector<vector<int>>& graph) {
        int size = graph.size();
        vector<int> ans;
        int color[size];
        if(size == 0){
            return ans;
        }
        memset(color, 0, sizeof(color));
        //dfs
        for(int i = 0; i < size; i++){
            if(travel(graph, i, color)){
                ans.push_back(i);
            }
        }
        return ans;
    }
    bool travel(vector<vector<int>>& graph, int node, int* color){
        if(color[node] == 1){
            return true; //it means it is safe
        }else if(color[node] == 2){
            return false; // not safe
        }
        color[node] = 2;
        for(int i = 0; i < graph[node].size(); i++){
            if(travel(graph, graph[node][i], color) == false){
                return false;
            }
        }
        color[node] = 1;
        return true;
    }
};

用一个for循环从0开始遍历所有的点,DFS时,后面的点如果访问到一个不安全的点,说明这个点也是不安全的。因为每个点只会被访问一次,所以算法的复杂度是 O ( V + E ) O(V+E) .

猜你喜欢

转载自blog.csdn.net/pjsfirstlaw/article/details/82957265