[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:
graphwill have length at most10000.- 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].
在一个有向图中,如果从一个节点出发走过很多步之后到达了终点(出度为0的节点,无路可走了),则认为这个节点是最终安全的节点。如果根本停不下来,那就是在一个环上,就是不安全节点。要在自然数K步内停止,到达安全节点,返回满足要求的排序好的所有安全节点的索引值。实质是在一个有向图中找出不在环路上的节点。
解法:DFS,可采用染色的方法对节点进行分类:0表示该结点还没有被访问;1表示已经被访问过了,并且发现是safe的;2表示被访问过了,但发现是unsafe的。我们采用DFS的方法进行遍历,并返回该结点是否是safe的:如果发现它已经被访问过了,则直接返回是否是safe的标记;否则就首先将其标记为unsafe的,然后进行DFS搜索(此时该结点会处在DFS的路径上,所以后面的DFS一旦到了该结点,就会被认为是形成了环,所以直接返回false)。当整个DFS的搜索都已经结束,并且都没有发现该结点处在环上时,说明该结点是safe的,所以此时将其最终标记为safe即可。空间复杂度是O(n),时间复杂度是O(n)
解法2: 迭代,记录下每个节点的出度,如果出度为0那必然是环路外的节点,然后将该点以及指向该点的边删除,继续寻找出度为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 collections class 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)
# 用字段存储每个节点的父节点
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;
}
};
All LeetCode Questions List 题目汇总
[LeetCode] 802. Find Eventual Safe States 找到最终的安全状态的更多相关文章
- [LeetCode] Find Eventual Safe States 找到最终的安全状态
In a directed graph, we start at some node and every turn, walk along a directed edge of the graph. ...
- LeetCode 802. Find Eventual Safe States
原题链接在这里:https://leetcode.com/problems/find-eventual-safe-states/ 题目: In a directed graph, we start a ...
- 【LeetCode】802. Find Eventual Safe States 解题报告(Python)
[LeetCode]802. Find Eventual Safe States 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemi ...
- LC 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. ...
- 【leetcode】802. Find Eventual Safe States
题目如下: 解题思路:本题大多数人采用DFS的方法,这里我用的是另一种方法.我的思路是建立一次初始值为空的safe数组,然后遍历graph,找到graph[i]中所有元素都在safe中的元素,把i加入 ...
- 802. Find Eventual Safe States
https://leetcode.com/problems/find-eventual-safe-states/description/ class Solution { public: vector ...
- Java实现 LeetCode 802 找到最终的安全状态 (DFS)
802. 找到最终的安全状态 在有向图中, 我们从某个节点和每个转向处开始, 沿着图的有向边走. 如果我们到达的节点是终点 (即它没有连出的有向边), 我们停止. 现在, 如果我们最后能走到终点,那么 ...
- [Swift]LeetCode802. 找到最终的安全状态 | Find Eventual Safe States
In a directed graph, we start at some node and every turn, walk along a directed edge of the graph. ...
- LeetCode 277. Find the Celebrity (找到明星)$
Suppose you are at a party with n people (labeled from 0 to n - 1) and among them, there may exist o ...
随机推荐
- java代码转python代码
(1)安装工具(windows 环境下面) 先下载antlr: http://www.antlr3.org/download/antlr-3.1.3.tar.gz 链接:http://pan.baid ...
- P4139 上帝与集合的正确用法[欧拉定理]
题目描述 求 \[ 2^{2^{2\cdots}} ~mod ~p \] 简单题,指数循环节. 由于当\(b>=\psi(p)\)时,有 \[ a^b=a^{b ~mod~\psi(p)+\ps ...
- 学习Microsoft Visio(2)
常用业务设计图示法 一.业务设计基础 1.名词概念 业务流程图:在公司.部门.岗位的层面上描述一个业务流程的宏观过程. 基本流程图:对某个处理过程的详细逻辑流程进行描述. 静态业务对象图(UML表示法 ...
- node 日志 log4js 错误日志记录
SET DEBUG=mylog:* & npm start 原文出处:http://blog.fens.me/nodejs-log4js/ 1. 默认的控制台输出 我们使用express框架时 ...
- Python的私有变量与装饰器@property的用法
Python的私有变量是在变量前面加上双横杠(例如:__test)来标识, Python私有变量只能在类内部使用,不被外部调用,且当变量被标记为私有后,调用时需再变量的前端插入类名,在类名前添加一个下 ...
- System.getProperty、PropConfig.loadConfig应用
1.获取项目下制定位置(System.getProperty("admin.root")): 在web.xml中配置webAppRootKey <context-param& ...
- vsftp 匿名访问设置设置
本文通过MetaWeblog自动发布,原文及更新链接:https://extendswind.top/posts/technical/vsftpd_configuration vsftpd (very ...
- 更改matlab默认精度
我使用的是R2018a 1.打开预设 2.命令行窗口 3.变量
- Monkey框架(基础知识篇) - monkey启动与参数介绍
一.monkey启动 直接PC启动:> adb shell monkey [options] <count> shell 端启动:> adb shell >monkey ...
- ubuntu之路——day11.7 end-to-end deep learning
在传统的数据处理系统或学习系统中,有一些工作需要多个步骤进行,但是端到端的学习就是用一个神经网络来代替中间所有的过程. 举个例子,在语音识别中: X(Audio)----------MFCC----- ...