当前位置: 首页 > 知识库问答 >
问题:

如何使用itarative方法检测循环

田翔
2023-03-14

我正在努力学习如何检测循环。我看到很多使用递归的例子,但我想以迭代的方式实现。这是我的密码

public boolean cycleDetection(int[][] edges, int source ) {
     Map<Integer, List<Integer>> graph = new HashMap();
        for (int[] edge : edges) {
            graph.putIfAbsent(edge[0], new ArrayList());
            graph.get(edge[0]).add(edge[1]);
        }
        Stack<Integer> stack = new Stack();
        Set<Integer> visited = new HashSet();
        
        stack.push(source);
        visited.add(source);
        while(!stack.isEmpty()) {
            int curr = stack.pop();
            visited.add(curr);
            if(graph.containsKey(curr)) {
                for(int i :  graph.get(curr)) {
                    
                    if(visited.contains(i)) {
                        return true;
                    }
                    stack.push(i);
                }
            }
            
        }
    return false;
}

它没有按预期工作

    int[][] vertex = { {0 , 1 }, {0,3}, {1,2},{2,1} }; // Has Cycle
    int[][] vertex = { {0 , 1 }, {0,2}, {1,3},{2,3} }; // No Cycle

我在这里遗漏了什么逻辑?

共有1个答案

荀振国
2023-03-14

问题是你也在检测交叉边。

在您的示例中,发现顺序(在示例2中)是:

0 -> 1 -> 3 -> 2 -> 3

现在,当你第二次看到3时——你注意到它已经被访问过了——然后说有一个循环。然而,这是一个交叉边——你发现了它,但通过一个不同的分支,事实上这不是一个循环。

一种解决方案(对代码进行最少的修改)-虽然可能不是最佳方案,但一旦您完成了探索,就从访问的中删除一个节点。

为什么它会起作用?

  • 如果有一个循环——你会发现它,因为在你重新发现它之前,节点并没有从访问的数据库中删除。一旦你发现了算法,它就会结束
  • 如果没有循环,您将耗尽一条路径,并将其所有节点从访问的路径中移除。由于没有循环,算法将“耗尽”选项并最终终止

在DFS的迭代代码版本中实现可能有点棘手(因为您希望“一旦从递归中恢复”就模仿这样做),但应该是可能的。祝你好运!

 类似资料:
  • 问题内容: 我想编写一个简单的Java代理,它可以打印所检测的Java程序调用的方法的名称。 例如,我要检测的Java程序是: 我想显示这样的东西: 谢谢你的帮助! 问题答案: 您可以使用Javassist之类的工具库来执行此操作。 让我为您提供一个方法的示例,您可以使用Javassist或反射将其扩展到所有方法: 检查此链接以获取详细信息: http // www.csg.ci.iu- toky

  • 我试图用BFS算法在有向图中检测循环。我检测周期的主要想法是:由于BFS只访问每个节点(和边缘)一次,如果我再次遇到已访问的节点;它会导致一个循环。然而,我的代码有时会找到循环,有时不会。 我从维基百科修改的伪代码如下: 我错过了什么?

  • 我知道这有点难,但我正在学习普林斯顿大学的算法课程。我尝试使用Bellman-Ford算法来检测边加权有向图中的负圈。 完整的代码实现可从以下网址获得:BellmanFordSP。java和EdgeWeightedDirectedCycle。JAVA具体来说,我被困在这一点上: 这个条件表示什么:。为什么我们只在这个特定的条件下检查负循环?

  • 问题内容: 假设你在Java中拥有一个链表结构。它由节点组成: 每个节点都指向下一个节点,但最后一个节点除外,后者的下一个为空。假设列表有可能包含一个循环-即最终的Node而不是null,而是引用了列表中位于其之前的节点之一。 最好的写作方式是什么 如果给定的是带有循环的列表的第一个,则将返回什么,否则返回?你怎么写才能占用恒定的空间和合理的时间? 问题答案: 想法是要有两个引用列表,并以不同的速

  • 我在不需要的if-else代码分支中使用了标记方法:这些分支并不慢,但在相反的分支中有一个更高效的实现。现在,我想使用JProfiler找出这些不需要的分支的所有路径(包括它们的重要性),以修复代码,从而运行到首选分支。此外,我希望以最少的分析开销进行检测/测量。 我发现采样不起作用,因为标记方法执行得太快,无法将其显示在热点中。此外,它可能执行得不够频繁。 我也不知道用仪器来做。同样,这种方法甚