【问题标题】:Loop/Cycle detection in a linked list in JavaJava中链表中的循环/循环检测
【发布时间】:2017-07-30 14:55:02
【问题描述】:

问题: 给定一个循环链表,实现一个算法,返回循环开始时的节点。

我不是要求回答这个问题!

我知道有一些循环检测算法涉及以不同速度移动的两个指针,并且我已经知道了这个问题的一些答案。

但是,我想知道的是,当我第一次尝试解决这个问题时,我是这样接近的:

LinkedListNode loopExists(LinkedListNode node) {
    HashSet hs = new HashSet();
    while(node != null) {
        if(hs.contains(node))
            return node;
        else
            hs.add(node);
        node = node.next;
    }
    return null;
}

我很好奇,因为没有像我上面发布的那样的答案。

问题是在循环开始时询问节点。

如果我遍历链表检查每个节点(不是 node.data)并且如果我再次找到相同的节点,我假设这是循环开始处的节点。

这种方法有什么问题吗?如果我有什么误解,请告诉我。谢谢!

【问题讨论】:

  • 这样的问题更多属于codereview.stackexchange.com
  • 如何定义循环的开始?它可以是循环中的任何节点,除非我误解了这个问题。
  • 循环没有“开始”。
  • 输入:A -> B -> C -> D -> E -> C 输出:C 我的意思是循环的开始和结束(重复)

标签: java loops linked-list nodes


【解决方案1】:

是的,当然,我们可以有多种解决方案。而且,如果没有解决方案,那么这并不意味着它不能成为解决方案。

例如,另一种解决方案可能是,我们可以在每个节点中具有flag 属性,并在访问时标记checked。在这种情况下,如果同一节点再次重复,那么我们可以检查flag属性并检测循环。

现在,在您的情况下,您正在使用不必要的内存来存储节点对象,这可以通过运行循环在不存储节点对象的情况下解决。

【讨论】:

  • 我同意 Ravi 关于内存的评论:HashSet 将暂时占用与您的列表大小大致成比例的内存。但这是一个非常简单易读的实现,没有任何问题。速度不同的两个指针占用恒定内存(2 个指针),但生成的代码几乎不可读(如果您碰巧不知道算法)。我强烈反对引入“标志”字段。像 loopExists() 这样的方法不应该改变参数 LinkedList 的任何状态。
  • 谁能详细说明我的解决方案是使用不必要的内存来存储节点对象?我是新手,在这里我不太明白,但我之前读过关于记忆的文章:(
  • @NomaCitzen 好的,首先你要创建一个HashSet 的实例,它会占用一些内存。对 ?现在,一旦开始循环,在每次迭代中,您将存储每个节点的引用,该引用将继续增长,直到找到循环。
  • @NomaCitzen 你需要澄清你的疑问,一旦你得到答案。你需要练习接受它。
猜你喜欢
  • 2011-12-04
  • 2015-03-03
  • 1970-01-01
  • 2012-01-06
  • 1970-01-01
  • 2021-01-18
  • 2018-12-17
相关资源
最近更新 更多