【问题标题】:Displacement of unsorted shifted array未排序的移位数组的位移
【发布时间】:2017-03-12 12:57:13
【问题描述】:

我们有一个未排序的数组,其中包含不同的条目 a_1, a_2, ... a_n,我们还知道一个移位数组 a_(nk), ...a_n, a_1, a_2, ... 我们的目标是找到给定这两个数组的位移 k。当然有一个最坏情况的线性算法 O(n)。但我们能做得比这更好吗?

提示答案与 k 分布有关。如果 k 在 0 和 n 之间均匀分布,那么我们必须在 O(n) 内完成。如果 k 以其他方式分布,可能会有更好的方式。

【问题讨论】:

  • @greybeard 这是个好主意。似乎 BM 算法可能在这里工作,如果 k 很小,那么仍然 O(k) 应该是答案。如果 k 很大(接近 n),那么我们可以尝试 BM 算法。例如,我们选择原始数组的第一个 n/7 条目作为匹配目标。我们预处理 n/7 数组:构建一个哈希表。由于每个条目是不同的,那么我们可以从匹配最后一个条目开始,如果最后一个条目不匹配并且在哈希表中不存在,我们可以跳转 n/7 数组。因此,对于较大的 k,我们可以找到 O(cn) 方法,但前因子 c 较小。
  • @greybeard 我们可以选择长度为sqrt(n),那么我们可能会得到O(sqrt(n))
  • (对于“随机”内容,您可能会得到 预期 o(n),但请尝试使用几乎所有相同的元素来了解最坏情况 .) 太复杂了——只需搜索移位数组中原始数组的前半部分 a₁…aₚ, p=n/2。 (好的,有类似奇数 n=2p+1(p:前缀/模式的长度)的尼特,在 p+1 处匹配:如果“其余”不匹配,则必须在 p+2 处处理可能的匹配”手动”。)

标签: arrays algorithm sorting complexity-theory


【解决方案1】:

如果数组中没有重复项(不同的条目),我将使用 while 循环并从 0 开始递增索引值 k 并同时比较两个项目,一个从开始,一个从结束。如array1[k] === array2[0]array1[n-k] === array[0],索引值k应该是上述比较返回true时的位移。

【讨论】:

  • 最佳情况 O(k),最坏情况 O(n)。不过我也会这样做
【解决方案2】:

有一个 O(sqrt(n)) 解决方案,正如操作人员根据 @greybeard 的提示得出的那样。

从第一个列表中,散列第一个 sqrt(n) 元素。对于第二个列表,查看每次按 sqrt(n) 个元素前进的元素。

但是,如果 k 小而 n 大,我们可能会问是否有可能接近 O(k)(或更小!)的解决方案。事实上,我声称有一个 O(sqrt(k)) 解决方案。

为此,我提出了增加步长的增量过程。所以算法看起来是这样的:

首先,从第一个列表中获取 2 个元素 - 对这些值进行哈希处理(并将值的位置作为查找值,所以这应该被认为是一个 HashMap,其中键是列表的元素,值是位置)。 将这些元素与第二个列表中的第一个和第三个元素进行比较。 也散列第二个列表中的值。 接下来,查看第一个列表中的第三个元素 - 散列值。在此过程中,查看它是否与第二个列表中的任何一个元素匹配。接下来,在第二个列表中推进 3 个元素,并比较它的值 - 记住这些值。

像这样继续: 增加第一个列表的前缀长度,并在每个点增加第二个列表的步长。每当您为第一个列表获取新元素时,您都必须将其与第二个列表中的值进行比较,但这很好,因为它不会显着影响性能。

请注意,当您的前缀长度为 p 时,您已经检查了第二个列表中的第一个 p*(p+1)/2 个元素。所以对于给定的 k 值,这个过程将要求前缀长度 p 大约为 sqrt(2k),根据需要为 O(sqrt(k))。

【讨论】:

    【解决方案3】:

    基本上,如果我们知道a[0] 不等于b[0],我们就不需要检查a[1] 是否等于b[1]。扩展这个想法并散列a's,检查可以如下:

    a[0] == b[0] or b[0] in hash?   => known k's: 0
    a[1] == b[2] or b[2] in hash?   => known k's: 0,1,2
    a[2] == b[5] or b[5] in hash?   => known k's: 0,1,2,3,4,5
    a[3] == b[9] or b[9] in hash?   => known k's: 0,1,2,3,4,5,6,7,8,9
    a[4] == b[14] or b[14] in hash? => known k's: 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14
    ...
    

    (我认为这是O(sqrt n) 时间和空间最坏情况复杂度。)

    【讨论】:

      【解决方案4】:

      也许如果你将它们合并到一个哈希表中。那么原始数组中 a(n-k) 的访问和比较时间将为 O(1)。

      【讨论】:

      • 构建一个哈希表的时间至少是O(n)吧?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-25
      • 1970-01-01
      • 2019-01-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多