[Leetcode] 802. Find eventual safe States find the final security status

Source: Internet
Author: User

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 isEventually safeIf and only if we must eventually walk to a terminal node. More specifically, there exists a natural numberKSo that for any choice of where to walk, we must have stopped at a terminal node in lessKSteps.

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

The directed graph hasNNodes with labels0, 1, ..., N-1, WhereNIs the lengthgraph. The graph is given in the following form:graph[i]Is a list of labelsjSuch 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:

  • graphWill have length at most10000.
  • The number of edges in the graph will not exceed32000.
  • Eachgraph[i]Will be a sorted list of different integers, chosen within the range[0, graph.length - 1].

In a directed graph, if a node reaches the end point after many steps are taken from a node (the node with an outbound degree of 0 has no way to go), the node is considered as the final safe node. If it cannot be stopped, it is on a ring, that is, an insecure node. Stop in the natural K step to reach the security node, return the index value of all the security nodes that meet the requirements. The essence is to find nodes that are not on the loop in a directed graph.

Solution: DFS. nodes can be classified by dyeing. The value 0 indicates that the node has not been accessed. The value 1 indicates that the node has been accessed and found to be safe; 2 indicates that it has been accessed but found to be unsafe. We use the DFS method to traverse and return whether the node is safe: if it is found that it has been accessed, it will directly return whether it is a safe flag; otherwise, it will be marked as unsafe first, and then the DFS search will be performed (the node will be located in the DFS path at this time, so once the subsequent DFS arrives at this node, it is regarded as forming a ring, so false is returned directly ). When the entire DFS search is complete and the node is not found on the ring, it indicates that the node is safe, so mark it as safe. The space complexity is O (n), and the time complexity is O (n)

Solution 2: iterations record the degree of exit of each node. If the degree of exit is 0, it must be a node outside the loop, and then delete the vertex and the edge pointing to the vertex, continue to find the point with the outbound degree of 0

class Solution {    public List<Integer> eventualSafeNodes(int[][] graph) {        List<Integer> res = new ArrayList<>();        if(graph == null || graph.length == 0)  return res;                int nodeCount = graph.length;        int[] color = new int[nodeCount];                for(int i = 0;i < nodeCount;i++){            if(dfs(graph, i, color))    res.add(i);        }                return res;    }    public boolean dfs(int[][] graph, int start, int[] color){        if(color[start] != 0)   return color[start] == 1;                color[start] = 2;        for(int newNode : graph[start]){            if(!dfs(graph, newNode, color))    return false;        }        color[start] = 1;                return true;    }}

Python:

def eventualSafeNodes(self, graph):    """    :type graph: List[List[int]]    :rtype: List[int]    """    n = len(graph)    out_degree = collections.defaultdict(int)    in_nodes = collections.defaultdict(list)     queue = []    ret = []    for i in range(n):        out_degree[i] = len(graph[i])        if out_degree[i]==0:            queue.append(i)        for j in graph[i]:            in_nodes[j].append(i)      while queue:        term_node = queue.pop(0)        ret.append(term_node)        for in_node in in_nodes[term_node]:            out_degree[in_node] -= 1            if out_degree[in_node]==0:                queue.append(in_node)    return sorted(ret)

Python:

# Time:  O(|V| + |E|)# Space: O(|V|)import collectionsclass Solution(object):    def eventualSafeNodes(self, graph):        """        :type graph: List[List[int]]        :rtype: List[int]        """        WHITE, GRAY, BLACK = 0, 1, 2        def dfs(graph, node, lookup):            if lookup[node] != WHITE:                return lookup[node] == BLACK            lookup[node] = GRAY            for child in graph[node]:                if lookup[child] == BLACK:                    continue                if lookup[child] == GRAY or                    not dfs(graph, child, lookup):                    return False            lookup[node] = BLACK            return True        lookup = collections.defaultdict(int)        return filter(lambda node: dfs(graph, node, lookup), xrange(len(graph)))

Python:

Class solution (object): def eventualsafenodes (self, graph): "": Type graph: list [list [int]: Rtype: list [int] "if not graph: return [] n = Len (graph) # store the parent node D = {u: [] for u in range (n)} degree = [0] * n for u in range (n): For V in graph [u]: d [v]. append (u) degree [u] = Len (graph [u]) q = [U for u in range (N) if degree [u] = 0] res = [] While Q: node = Q. pop () res. append (node) for nodes in D [node]: Degree [nodes]-= 1 If degree [nodes] = 0: Q. append (nodes) return sorted (RES)

C ++:

class Solution {public:    vector<int> eventualSafeNodes(vector<vector<int>>& graph) {        vector<int> res;        if (graph.size() == 0) {            return res;        }        int size = graph.size();        vector<int> color(size, 0);         // 0: not visited; 1: safe; 2: unsafe.        for (int i = 0; i < size; ++i) {            if (dfs(graph, i, color)) {     // the i-th node is safe                res.push_back(i);            }        }        return res;    }private:    bool dfs(vector<vector<int>> &graph, int start, vector<int> &color) {        if (color[start] != 0) {            return color[start] == 1;        }        color[start] = 2;       // mark it as unsafe because it is on the path        for (int next : graph[start]) {            if (!dfs(graph, next, color)) {                return false;            }        }        color[start] = 1;       // mark it as safe because no loop is found        return true;    }};

  

 

 

 

[Leetcode] 802. Find eventual safe States find the final security status

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.