我正在努力学习如何检测循环。我看到很多使用递归的例子,但我想以迭代的方式实现。这是我的密码
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
我在这里遗漏了什么逻辑?
问题是你也在检测交叉边。
在您的示例中,发现顺序(在示例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找出这些不需要的分支的所有路径(包括它们的重要性),以修复代码,从而运行到首选分支。此外,我希望以最少的分析开销进行检测/测量。 我发现采样不起作用,因为标记方法执行得太快,无法将其显示在热点中。此外,它可能执行得不够频繁。 我也不知道用仪器来做。同样,这种方法甚