检查两个链表是否在任何点合并的最佳可能算法?如果是的话,在哪里?

时间:2009-12-01 14:24:05

标签: linked-list

  

可能重复:
  Linked list interview question

这是一个面试问题,我没有答案。 给出两个列表,你不能改变列表,你不知道长度。 提供最佳算法:

  1. 检查两个列表是否在任何时候合并?
  2. 如果合并,他们在什么时候合并?
  3. 如果我允许您更改列表,您将如何修改算法?

4 个答案:

答案 0 :(得分:5)

我假设我们正在谈论简单的链表,我们可以安全地创建列表元素指针的哈希表。

Q1:迭代结束两个列表,如果相应的最后一个元素相同,则列表会在某个时刻合并。

复杂性 - O(N),空间复杂度 - O(1)

Q2:

  1. 将一个列表的所有元素放入哈希表
  2. 迭代第二个列表,探查列表中每个元素的哈希表。第一个命中(如果有的话)是合并点,我们在第二个列表中有位置。
  3. 要获取第一个列表中的位置,请再次遍历第一个列表,查找上一步中找到的元素。
  4. 时间复杂度 - O(N)。空间复杂度 - O(N)

    Q3:

    1. 作为Q1,但也反转了列表指针的方向。
    2. 然后迭代反向列表,查找最后一个公共元素 - 即合并点 - 并将列表恢复为原始订单。
    3. 时间复杂度 - O(N)。空间复杂度 - O(1)

答案 1 :(得分:1)

数字1:只需迭代两者,然后检查它们是否以相同的元素结束。那是O(n)并且它不能被打败(因为它可能是最常见的最后一个元素,到那里总是需要O(n))。

答案 2 :(得分:1)

  1. 将这两个列表并行运行一个元素,将每个元素添加到受访节点集(可以是哈希映射,或简单集,您只需要检查您之前是否访问过该节点)。在每一步检查您是否访问过该节点(如果是,那么它是合并点),如果您第一次访问节点,则将其添加到节点集。另一个版本(由@reinier指出)是仅走第一个列表,将其节点存储在Set中,然后仅针对该Set检查第二个列表。当列表提前合并时,第一种方法会更快,因为您不需要存储第一个列表中的所有节点。第二种情况更好,在最坏的情况下,两个列表根本不合并,因为它没有存储集合中的第二个列表中的节点
  2. 见1。
  3. 您可以尝试标记每个节点,而不是Set,但如果您无法修改结构,那么它就没那么有用了。您也可以尝试取消链接每个被访问节点并将其链接到某个保护节点(如果您在遍历时遇到它,则在每一步检查)。如果列表足够长,它会为Set节省内存。

答案 3 :(得分:-2)

遍历列表并有一个全局变量来查找遇到的NULL个数。如果他们在某个时刻合并,那么只有1 NULL,那么会有两个NULL

相关问题