一尘不染

如何仅使用两个内存位置来确定链表是否具有循环

algorithm

没有人知道一种算法,该算法仅使用两个变量来遍历列表是否会在自身上循环。假设您有一个对象链接列表,那么什么类型的对象都没有关系。我在一个变量中有一个指向链表头的指针,并且只给了另一个变量来遍历链表。

所以我的计划是比较指针值以查看是否有任何指针相同。该列表的大小是有限的,但可能很大。我可以将两个变量都设置为开头,然后使用另一个变量遍历列表,始终检查它是否等于另一个变量,但是,如果我碰到了一个循环,我将永远不会离开它。我认为这与遍历列表和比较指针值的不同速率有关。有什么想法吗?


阅读 198

收藏
2020-07-28

共1个答案

一尘不染

我建议使用Floyd's Cycle-Finding Algorithm aka The Tortoise and the Hare Algorithm。它具有O(n)复杂度,我认为它符合您的要求。

示例代码:

function boolean hasLoop(Node startNode){
  Node slowNode = Node fastNode1 = Node fastNode2 = startNode;
  while (slowNode && fastNode1 = fastNode2.next() && fastNode2 = fastNode1.next()){
    if (slowNode == fastNode1 || slowNode == fastNode2) return true;
    slowNode = slowNode.next();
  }
  return false;
}

有关Wikipedia的更多信息:Floyd的循环查找算法

2020-07-28