赞
踩
有一个有 n 个节点的有向图,节点按 0 到 n - 1 编号。图由一个 索引从 0 开始 的 2D 整数数组 graph表示, graph[i]是与节点 i 相邻的节点的整数数组,这意味着从节点 i 到 graph[i]中的每个节点都有一条边。
如果一个节点没有连出的有向边,则该节点是 终端节点 。如果从该节点开始的所有可能路径都通向 终端节点 ,则该节点为 安全节点 。
返回一个由图中所有 安全节点 组成的数组作为答案。答案数组中的元素应当按 升序 排列。
(上图)输入:graph = [[1,2],[2,3],[5],[0],[5],[],[]]
输出:[2,4,5,6]
输入:graph = [[1,2,3,4],[1,2],[3,4],[0,4],[]]
输出:[4]
n == graph.length
1 <= n <= 104
0 <= graph[i].length <= n
0 <= graph[i][j] <= n - 1
graph[i] 按严格递增顺序排列。
图中可能包含自环。
图中边的数目在范围
[
1
,
4
∗
1
0
4
]
[1,4*10^4]
[1,4∗104] 内。
1、答案学习思路:深搜+三色标记法。主要思路是,根据边深搜,递归查询,发现环路之后,整条路上的其实都可以认定为不安全结点。只有所有的边都通往安全节点才是安全节点。
2、拓扑排序(容易想到)
package leetcode802; import java.util.*; class Solution802 { //拓扑排序 public List<Integer> eventualSafeNodes(int[][] graph) { Set<Integer>[] Source_graph = new HashSet[graph.length]; int[] Target_graph = new int[graph.length]; List<Integer> result = new ArrayList<>(); for (int i=0;i<graph.length;i++) { Source_graph[i] = new HashSet<>(); Target_graph[i] = graph[i].length; } for (int i=0;i< graph.length;i++) for (int j=0;j<graph[i].length;j++) Source_graph[graph[i][j]].add(i); Queue<Integer> q = new ArrayDeque<>(); for (int i=0;i<Target_graph.length;i++) { if (Target_graph[i]==0) { q.offer(i); result.add(i); } } while(!q.isEmpty()){ int now_source = q.poll(); for (Integer i :Source_graph[now_source]) { Target_graph[i]--; if (Target_graph[i]==0) {q.offer(i);result.add(i);} } } Collections.sort(result); return result; } } class Solution802_2 { //深搜+三色标记 public List<Integer> eventualSafeNodes(int[][] graph) { int[] color = new int[graph.length]; List<Integer> ans = new LinkedList<Integer>(); for (int i=0;i<graph.length;i++) if (safe(graph,color,i)) ans.add(i); Collections.sort(ans); return ans; } public boolean safe(int[][] graph,int[] color,int x) { if (color[x]!=0) return color[x]==2; color[x] = 1; for (int i:graph[x]) if (!safe(graph,color,i)) return false; color[x] = 2; return true; } } public class leetcode802 { public static void main(String[] args) { Scanner cin = new Scanner(System.in); int n = cin.nextInt(); cin.nextLine(); int[][] graph = new int[n+1][]; for (int i =0;i<=n;i++){ String line = cin.nextLine(); if (line.isEmpty()) { graph[i] = new int[0]; continue; } String[] numbers = line.split(" "); graph[i] = new int[numbers.length]; for (int j=0;j<numbers.length;j++) graph[i][j] = Integer.parseInt(numbers[j]); } cin.close(); // Solution802 s = new Solution802(); Solution802_2 s_2 = new Solution802_2(); // System.out.println(s.eventualSafeNodes(graph)); System.out.println(s_2.eventualSafeNodes(graph)); // input // 6 // 1 2 // 2 3 // 5 // 0 // 5 } }
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/find-eventual-safe-states
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。