【问题标题】:Find loop in a linked list containing millions of nodes在包含数百万个节点的链表中查找循环
【发布时间】:2016-03-29 11:37:30
【问题描述】:

这是在一次采访中问我的。我知道解决这个问题的几种方法。但重点是它包含数百万个节点

我知道我们可以使用两个指针方法解决这个问题。我们也可以使用 HashMap 来解决这个问题。他想知道优化的解决方案,因为该列表有 数百万 个节点。

在那之后,我还建议将列表分成多个块,然后应用多线程来加快进程。但他并不完全满意。有没有其他我不关注的方式。使用多线程,我们还必须维护一组已访问的下一个节点,因为在将列表划分为块时,循环可能被分为两部分。

我不要求任何实施。只是给我一些方向,这样我就可以更多地思考它。

【问题讨论】:

  • 为什么你认为 HashMap 方法效率不高?
  • HashMap 方法是有效的。我把这件事告诉了他。但他想要更多的优化。使用 HashMap 我们必须遍历所有节点,并且存在数百万个节点。
  • 如果您怀疑列表包含循环,您将如何将列表分成块?是的,当然,您必须遍历所有节点。如果最后一个自己循环怎么办?
  • 这就是他对多线程方法不满意的原因。
  • @UlrichEckhardt - 同意,我开始思考与这个问题无关的其他事情。

标签: algorithm data-structures linked-list


【解决方案1】:

如果你开始使用 Floyd 算法(两分法),然后面试官希望你更快地提出建议,那么你就走错了方向。 HashMap 的维护将花费方式 更长的时间。多线程也没有用,因为它是一个链表,你必须遍历它来划分工作。

我会从布伦特算法开始,它比弗洛伊德算法遵循的指针更少,而且通常更快,因为它对缓存友好。维基百科在这里对布伦特的算法有很好的描述:https://en.wikipedia.org/wiki/Cycle_detection#Brent.27s_algorithm

还可以通过各种方式加速 Brent 算法。布伦特算法确保您访问的节点数量不会超过您真正需要找到循环的两倍。例如,通过在 simple 单向关联散列(无冲突避免)中存储 1 个以上的前一个节点,您可以减少这个因子,直到它任意接近 1。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-25
    • 1970-01-01
    • 2012-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多