【问题标题】:Efficiently searching a common node in 2 singly linked lists with a memory constraint?有效地搜索具有内存约束的 2 个单链表中的公共节点?
【发布时间】:2014-04-15 17:31:01
【问题描述】:

假设您有两个符号链接列表,它们在某个时候组合在一起。设计一个 O(n+m) 算法,使用不超过 O(1) 的内存来找到 FIRST 公共节点,其中 m 和 n 是从列表的头部到列表的距离帮派点,分别。

我想标记访问过的节点,但后来意识到它需要的内存超过 O(1)。 当您可以在整个列表上运行时,问题很容易,由于运行时限制,此处不允许这样做。帮助=D

【问题讨论】:

  • 你能解释一下mn的定义吗?您只描述了其中一个,不清楚是哪一个。
  • 哦,我想我明白了 - 你的意思是 m 是从一个列表的头部到第一个公共节点的距离,n 是从另一个列表的头部的距离到第一个公共节点?
  • 是否允许我们改变原始列表,只要它不涉及任何新分配?
  • 您应该考虑详细说明“联合起来”的确切含义。
  • @AaronDufour 是的,你是对的。

标签: algorithm data-structures linked-list runtime time-complexity


【解决方案1】:

我假设有一种方法可以将第一个列表中的元素 x 与第二个列表中的元素 y 进行比较,以确定它们是否引用了相同的元素,超出了帮派点。

  • 将第一个列表中的 x1 与第二个列表的前两个元素 y1y2 进行比较。
  • y1x1x2 进行比较。
  • 比较 x2y2 ... y4
  • 比较 y2x2 ... x4
  • 比较 x4y4 ... y8
  • ...

一般:

for q in 1, 2, 4, 8, 16, ...
    Compare x_q with y_q ... y_2q
    Compare y_q with x_q ... x_2q

基本上,在每一步中,您都会将搜索范围扩大一倍。假设m <= n。然后在某个时候出现m<qn-m<q。现在您将找到匹配项x_q==y_(q+n-m)。这场比赛在帮派点之外的某个地方,从那里你只需要回到帮派点。这是O(n+m)

编辑好的,返回部分不适用于单链表。然而,这是一个次要的技术问题,因为此时我们知道n-m 的区别,并且可以从头开始重新搜索,将x_ky_(k+n-m) 比较所有k=1,2,3,...,直到找到匹配项。

Edit2 复杂性,证明的粗略概述。对于每个q,我们都会进行2*q 比较。假设我们找到了q=q1 的匹配项。然后对所有qq1 求和,总共给出4*q1 比较,即几何级数的总和。现在我们只需要证明q1=O(n+m)。我们知道没有匹配到q=q1/2,这意味着m>q1/2n>2*q1/2,否则会有匹配。这可以写成n+m>q1/2q1<2*(n+m)。对于比较次数,我们得到4*q1<8*(n+m),它在O(n+m) 范围内。这里我们总是假设n>=m,而不失一般性。最后,我们必须添加 go back 部分,但这也是线性的,所以总算法是O(n+m),因为每个部分都是。

【讨论】:

  • “你只需要回到帮派点”是一个不平凡的操作(它可以在O(n+m) 中完成,但不明显如何)。事实上,“返回”会让人更加困惑——你不能向后遍历单链表,正如这所暗示的那样。
  • 谢谢。我改编了文字。
  • 你能解释一下为什么这是O(n+m)吗?看起来应该是,但我无法证明。
  • 完成。这样的事情很麻烦,因为出于某种原因,我们不能在这里真正写数学。
  • 我们必须找到第一个公共节点,这样我们会找到一个不是(大多数时候)第一个公共节点的公共节点。如果我们找到了那个节点,我们怎么才能找到第一个呢?即使我们必须从头开始?我们怎么知道在哪里停下来?
猜你喜欢
  • 1970-01-01
  • 2020-10-31
  • 2021-12-27
  • 1970-01-01
  • 2013-08-12
  • 2018-06-13
  • 2016-04-29
  • 2015-01-17
  • 2020-12-08
相关资源
最近更新 更多