赞
踩
在一个有向图中,我们从某个节点开始,每次沿着图的有向边走。 如果我们到达一个终端节点(也就是说,它没有指向外面的边),就停止。
现在,如果说我们的起始节点“最终是安全的”,当且仅当我们最终可以走到终端节点。 更具体地说,存在自然数K,对于任何行走的路线,我们必须在少于K步的情况下停在终端节点。
哪些节点是最终安全的? 返回它们升序排列的数组。
有向图具有N个节点,其标签为0, 1, ..., N-1,其中N是图的长度。 该图以下面的形式给出: graph[i]
是从i出发,通过边(i, j),所有能够到达的节点j组成的链表。
样例
样例1
- 输入: [[1,2],[2,3],[5],[0],[5],[],[]]
- 输出: [2,4,5,6]
样例2
- 输入: [[4,9],[3,5,7],[0,3,4,5,6,8],[7,8,9],[5,6,7,8],[6,7,8,9],[7,9],[8,9],[9],[]]
- 输出: [0,1,2,3,4,5,6,7,8,9]
- 分析
- 这道题给了我们一个有向图,然后定义了一种最终安全状态的结点,就是说该结点要在自然数K步内停止,所谓停止的意思,就是再没有向外的边,即没有出度,像上面例子中的结点5和6就是出度为0,因为graph[5]和graph[6]均为空。那么我们分析题目中的例子,除了没有出度的结点5和6之外,结点2和4也是安全状态结点,为啥呢,我们发现结点2和4都只能到达结点5,而结点5本身就是安全状态点,所以2和4也就是安全状态点了,所以我们可以得出的结论是,若某结点唯一能到达的结点是安全状态结点的话,那么该结点也同样是安全状态结点。那么我们就可以从没有出度的安全状态往回推,比如结点5,往回推可以到达结点4和2,先看结点4,此时我们先回推到结点4,然后将这条边断开,那么此时结点4出度为0,则标记结点4也为安全状态结点,同理,回推到结点2,断开边,此时结点2虽然入度仍为2,但是出度为0了,标记结点2也为安全状态结点
-
-
- 思路1、DFS
- 1、使用 dfs 遍历有向图的解法,经过分析某些结点不是安全状态,因为有环的存在,而环经过的所有结点,一定不是安全状态结点,所以我们可以通过DFS遍历有向图来找出环即可。在大多数的算法中,经典的DFS遍历法对于结点都有三种状态标记 UNKNOWN(0) SAFE(1) UNSAFE(-1),如果当前节点不是 UNKNOWN 的,表示改节点已经被访问过了,如果当前节点是 SAFE 返回 true 否则返回 false 。
- 2、然后开始遍历所有邻接结点,对该邻结点调用递归返回false了,说明当前结点是环结点,返回false。
-
- 思路2、BFS
- 1、遍历数组,使用 Map 记录每个节点的出度,只需先找到出度为 0 的数据存入 Queue
- 2、循环非空 Queue,取出队首元素,map包含改key,遍历 set 判断改节点是否存在,存在出度减 -1,存入 Queue
- 3、最后遍历数组indegree 如果出度为0 存入集合即可
-
-
-
- public class Solution {
-
- private static final int UNKNOWN = 0;
- private static final int UNSAFE = -1;
- private static final int SAFE = 1;
-
- /**
- * @param graph: a 2D integers array
- * @return: return a list of integers
- */
- public List<Integer> eventualSafeNodes(int[][] graph) {
- // write your code here
- int len = graph.length;
- int[] states = new int[len];
- List<Integer> result = new ArrayList<>();
- for (int i = 0; i < len; i++) {
- if (helper(i, graph, states)) {
- result.add(i);
- }
- }
- return result;
-
- }
-
- private boolean helper(int index, int[][] graph, int[] states) {
- if (states[index] != UNKNOWN) {
- return states[index] == SAFE;
- }
- states[index] = UNSAFE;
- for (int node : graph[index]) {
- if (!helper(node, graph, states)) {
- return false;
- }
- }
- states[index] = SAFE;
- return true;
- }
-
- }

-
- public class Solution {
- /**
- * @param graph: a 2D integers array
- * @return: return a list of integers
- */
- public List<Integer> eventualSafeNodes(int[][] graph) {
- // write your code here
- int len = graph.length;
- int[] = new int[len];
- Map<Integer, Set<Integer>> map = new HashMap<>();
- Queue<Integer> queue = new LinkedList<>();
- List<Integer> result = new ArrayList<>();
- for (int i = 0; i < len; i++) {
- int[] item = graph[i];
- for (int edge : item) {
- if (!map.containsKey(edge)) {
- map.put(edge, new HashSet<>());
- }
- map.get(edge).add(i);
- }
- indegree[i] = item.length;
- if (indegree[i] == 0) {
- queue.offer(i);
- }
- }
- while (!queue.isEmpty()) {
- Integer node = queue.poll();
- if (map.containsKey(node)) {
- Set<Integer> set = map.get(node);
- for (Integer i : set) {
- indegree[i]--;
- if (indegree[i] == 0) {
- queue.offer(i);
- }
- }
- }
- }
-
- for (int i = 0; i < len; i++) {
- if (indegree[i] == 0) {
- result.add(i);
- }
- }
- Collections.sort(result);
- return result;
- }
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。