find-eventual-safe-states
题目链接:find-eventual-safe-states
题目描述
在有向图中, 我们从某个节点和每个转向处开始, 沿着图的有向边走。 如果我们到达的节点是终点 (即它没有连出的有向边), 我们停止。现在, 如果我们最后能走到终点,那么我们的起始节点是最终安全的。 更具体地说, 存在一个自然数 K, 无论选择从哪里开始行走, 我们走了不到 K 步后必能停止在一个终点。哪些节点最终是安全的? 结果返回一个有序的数组。该有向图有 N 个节点,标签为 0, 1, …, N-1, 其中 N 是 graph 的节点数. 图以以下的形式给出: graph[i] 是节点 j 的一个列表,满足 (i, j) 是图的一条有向边。
题目分析
题目意思即找出非闭环的所有节点
- 我们可以从终点开始,即先找出那些没有出去的边的节点,即出度为0,这些节点一定符合条件,然后,反向搜索,找出他的上游,如果他的上游的所有出去的边都是在这些节点当中,则他的上游节点也是安全的。
- 我们还可以采用深搜的方式,对每个节点的所有出去的边进行搜索,如果他的所有下游节点都是安全的,则他也是安全的。
算法
反向边(Graph)
代码
class Solution {public List<Integer> eventualSafeNodes(int[][] G) {List<Set<Integer>> graph = new ArrayList<>(); // 正向边图List<Set<Integer>> rgraph = new ArrayList<>(); // 反向边图Queue<Integer> queue = new LinkedList<>(); // 安全节点队列List<Integer> result = new ArrayList<>(); // 返回结果集boolean[] safe = new boolean[G.length]; // 标记安全节点(因为返回结果要有序的,这里用空间换时间)// 图的初始化for (int i = 0; i < G.length; i++) {graph.add(new HashSet<Integer>());rgraph.add(new HashSet<Integer>());}for (int i = 0; i < G.length; i++) {for (int j : G[i]) {graph.get(i).add(j);rgraph.get(j).add(i);}if (G[i].length == 0) queue.offer(i);}while (!queue.isEmpty()) {// 安全节点集非空,出队并标记int i = queue.poll();safe[i] = true;for (int j : rgraph.get(i)) {// 移除上游节点到安全节点的边,如果上游节点的所有边都是到安全节点(即graph.get(j).isEmpty()),则入队graph.get(j).remove(i);if (graph.get(j).isEmpty()) queue.offer(j);}}// 读取标记,返回结果for (int i = 0; i < G.length; i++) {if (safe[i]) result.add(i);}return result;}
}
深度优先搜索(Depth-first-Search)
代码
import java.util.*;class Solution {// white表示未搜索,// black表示安全节点,// grey表示搜索中的节点或不安全节点enum Color {WHITE,BLACK,GREY,}public List<Integer> eventualSafeNodes(int[][] graph) {List<Integer> result = new ArrayList<>();if (graph.length == 0) return result;Color[] color = new Color[graph.length];Arrays.fill(color, Color.WHITE);for (int i = 0; i < graph.length; i++) {if (dfs(graph, i, color)) result.add(i);}return result;}public boolean dfs(int[][] graph, int i, Color[] color) {if (color[i] != Color.WHITE) return color[i] == Color.BLACK; // 节点i被搜索过,剪支,快速返回color[i] = Color.GREY; // 标记节点i在搜索中for (int child : graph[i]) {if (!dfs(graph, child, color)) return false; }color[i] = Color.BLACK; // 标记节点i安全return true;}
}
find-eventual-safe-states相关推荐
- LeetCode——802. 找到最终的安全状态(Find Eventual Safe States)[中等]——分析及代码(Java)
LeetCode--802. 找到最终的安全状态[Find Eventual Safe States][中等]--分析及代码[Java] 一.题目 二.分析及代码 1. 反图 + 拓扑排序 (1)思路 ...
- 【Lintcode】1015. Find Eventual Safe States
题目地址: https://www.lintcode.com/problem/find-eventual-safe-states/description 给定一个有向图,如果从某个顶点出发的任何路径都 ...
- LeetCode之Find Eventual Safe States(Kotlin)
问题: In a directed graph, we start at some node and every turn, walk along a directed edge of the gra ...
- leetcodee-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 grap ...
- leetcode 802. Find Eventual Safe States | 802. 找到最终的安全状态(有向图DFS)
题目 https://leetcode.com/problems/find-eventual-safe-states/ 题解 用 circle 表示所有环上节点和所有能到达环的节点. DFS,实际上每 ...
- leetcode 802. 找到最终的安全状态(Find Eventual Safe States)
目录 题目描述: 示例: 解法: 题目描述: 在有向图中, 我们从某个节点和每个转向处开始, 沿着图的有向边走. 如果我们到达的节点是终点 (即它没有连出的有向边), 我们停止. 现在, 如果我们最后 ...
- 802. Find Eventual Safe States [Medium]
/*** 自己的思路,DFS* 开始代码一直runtime error,看了discuss发现是因为helper里没有在进入递归前将dp[i]设为false* Runtime: 4 ms, faste ...
- 【LeetCode】深搜DFS(共85题)
[98]Validate Binary Search Tree [99]Recover Binary Search Tree [100]Same Tree [101]Symmetric Tree [1 ...
- Depth-first Search深度优先搜索专题3
473. Matchsticks to Square 思路:有n根长度不一的火柴,这些火柴可以拼接在一起,但不能被折断.这些火柴能够围城一个正方形吗?每个火柴可以并且必须使用一次.分析得到每个边的长度 ...
最新文章
- linux 下用户管理
- 用package.json配置NodeJS项目的模块声明
- mybatis默认的数据源连接池(PooledDataSource和UnPooledDataSource)
- 35岁电子工程师的艰难抉择
- [蓝桥杯][2019年第十届真题]后缀表达式(正解!!)
- hashmap为什么用红黑树_要看HashMap源码,先来看看它的设计思想
- Cheat Engine 教程( 1 - 9 通关 )
- Python编程从入门到实践~函数
- 基于Java+Jsp+SpringMVC漫威手办商城系统设计和实现
- 巧用HashSet装载非重数据(洛谷P2250题题解,Java语言描述)
- mysql工厂模式_设计模式-三种工厂模式实例
- 深入PHP内核之ZVAL
- 第十五章:交互式界面(十一)
- Linux 容器 vs 虚拟机 —— 谁更胜一筹
- Mysql间隔时间查询数据
- android手机双开微信方法,微信双开太简单了!学会这几种方法,就能同时登录2个微信...
- 网络和internet设置 代理 手动设置无效 | internet选项 代理设置无效无法应用 |internet选项代理修改后无法应用
- adb命令启动某个action_各种启动命令
- 简单的介绍一下腾讯的TAPD
- h5打开麦克风权限录音_和平精英麦克风权限怎么开 麦克风怎么是设置