当前位置:   article > 正文

JAVA程序设计:找到最终的安全状态(LeetCode:802)_leetcode802java

leetcode802java

在有向图中, 我们从某个节点和每个转向处开始, 沿着图的有向边走。 如果我们到达的节点是终点 (即它没有连出的有向边), 我们停止。

现在, 如果我们最后能走到终点,那么我们的起始节点是最终安全的。 更具体地说, 存在一个自然数 K,  无论选择从哪里开始行走, 我们走了不到 K 步后必能停止在一个终点。

哪些节点最终是安全的? 结果返回一个有序的数组

该有向图有 N 个节点,标签为 0, 1, ..., N-1, 其中 N 是 graph 的节点数.  图以以下的形式给出: graph[i] 是节点 j 的一个列表,满足 (i, j) 是图的一条有向边。

示例:
输入:graph = [[1,2],[2,3],[5],[0],[5],[],[]]
输出:[2,4,5,6]
这里是上图的示意图。

Illustration of graph

提示:

  • graph 节点数不超过 10000.
  • 图的边数不会超过 32000.
  • 每个 graph[i] 被排序为不同的整数列表, 在区间 [0, graph.length - 1] 中选取。

思路:本题其实就是找出有向图中存在的若干个环,并输出不会走到环上的所有节点。我的方法是通过深搜并保证每个点遍历的次数不超过一次。

  1. class Solution {
  2. private boolean mark;
  3. private boolean[] flag;
  4. private Set<Integer> ans;
  5. private Map<Integer,List<Integer>> map;
  6. public List<Integer> eventualSafeNodes(int[][] graph) {
  7. int n=graph.length;
  8. flag=new boolean[n];
  9. map=new HashMap<>();
  10. ans=new HashSet<>();
  11. for(int i=0;i<graph.length;i++) {
  12. map.put(i, new ArrayList<>());
  13. for(int j=0;j<graph[i].length;j++)
  14. map.get(i).add(graph[i][j]);
  15. }
  16. for(int i=0;i<n;i++) {
  17. if(flag[i] || ans.contains(i))
  18. continue;
  19. mark=false;
  20. dfs(i,new HashSet<>());
  21. }
  22. List<Integer> res=new ArrayList<>();
  23. for(int i=0;i<n;i++)
  24. if(!ans.contains(i))
  25. res.add(i);
  26. return res;
  27. }
  28. private void dfs(int index,Set<Integer> st) {
  29. if(mark) return;
  30. st.add(index);
  31. flag[index]=true;
  32. for(int i=0;i<map.get(index).size();i++) {
  33. int id=map.get(index).get(i);
  34. if(flag[id]) {
  35. if(st.contains(id) || ans.contains(id)) {
  36. mark=true;
  37. ans.addAll(st);
  38. return;
  39. }
  40. continue;
  41. }
  42. dfs(id,st);
  43. }
  44. st.remove(index);
  45. }
  46. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/995339
推荐阅读
相关标签
  

闽ICP备14008679号