【问题标题】:Find common elements in two sorted arrays [duplicate]在两个排序数组中查找公共元素[重复]
【发布时间】:2012-10-20 23:40:12
【问题描述】:

可能重复:
The intersection of two sorted arrays

我们有两个排序数组 A 和 B,除了将一个与其他数组中的所有元素进行比较之外,如何设计一个最佳算法来找到具有共同元素的数组?

【问题讨论】:

    标签: arrays algorithm language-agnostic


    【解决方案1】:

    持有两个指针:每个数组一个。

    i <- 0, j <- 0
    repeat while i < length(arr1) and j < length(arr2):
        if arr1[i] > arr2[j]: increase j
        else if arr1[i] < arr2[j]: increase i
        else : output arr[i], increase both pointers
    

    这个想法是,如果对数据进行排序,如果元素在一个数组中“太大”,那么对于数组中剩余的所有其他元素来说,它将“太大” - 因为它已排序。

    此解决方案需要对数据进行一次遍历。 O(n)(也有很好的常量)。

    【讨论】:

    • +1 - 用于提供可由 OP 转换为真实代码的伪代码解决方案。 (您可能还应该描述在边缘/结束情况下会发生什么。)
    • 这当然类似于归并排序。
    • @StephenC:你的意思是我假设一个数组被耗尽的情况?它基本上是停止条件......(我还假设一个元素在每个数组中出现两次你想打印两次)
    • 这就是我的意思。你的更新涵盖了它。
    • 复杂度是 O(m+n) 而不是 O(n)。 m 是第一个数组的大小,n 是第二个数组的大小。
    【解决方案2】:

    如果两个数组的长度(例如,A 具有 N 元素,B 具有 M 元素)相似,那么最好的方法是执行 线性 搜索一个数组的元素在另一个数组中。当然,由于数组已排序,下一次搜索应该从上一次搜索停止的地方开始。这是“排序数组合并”算法中使用的经典原理。 O(N + M) 的复杂性。

    如果长度明显不同(例如,M &lt;&lt; N),那么更优化的方法是遍历较短数组的元素并使用 binary 搜索在更长的数组。在这种情况下,复杂度是O(M * log N)

    如您所见,如果M 远小于N,则O(M * log N) 优于O(N + M),否则更糟。

    应该触发从一种方法切换到另一种方法的数组大小差异取决于一些实际考虑。如果应该根据您的数据进行实际实验来选择。

    这两种方法(线性和二进制搜索)可以“混合”成一个算法。让我们假设M &lt;= N。在这种情况下,让我们选择 stepS = [N / M]。您从数组A 中取出第一个元素,并使用步骤S 对数组B 中的元素执行跨接线性搜索,这意味着您检查元素B[0], B[S], B[2*S], B[3*S], ... 等等。一旦找到可能包含您正在搜索的元素的索引范围[S*i, S*(i+1)],您将切换到在数组B 的该段内进行二进制 搜索。完毕。对A 的下一个元素的跨接线性搜索从上一个搜索停止的地方开始。 (附带说明一下,选择 S 的值等于 2 的幂可能有意义)。

    这种“混合”算法是现有的两个排序数组的最渐近最优搜索/合并算法。然而,在实践中,根据数组的相对大小选择二进制或线性搜索的更简单方法效果很好。

    【讨论】:

    • 我想知道,在“混合”算法中,你为什么要对数组 B 进行二进制搜索,它的元素比 A 少?此外,您是否对以下声明有任何引用:“这种'混合'算法是现有两个排序数组的最渐近最优搜索/合并算法。” ?
    • @abc:如果我没记错的话,可以在“渐近高效的就地合并”文章中找到一个正式的证明(或对其中一个的引用):sciencedirect.com/science/article/pii/S0304397598001625
    【解决方案3】:

    除了将一个与其他数组中的所有元素进行比较

    您必须比较 A[] 和 B[] 才能知道它们是相同的——除非您非常了解它们可以保存什么样的数据。比较的性质可能有很多解决方案,可以根据需要进行优化。

    如果数组是非常严格地创建的,即只有已知模式的连续值并且总是从已知点开始,您可以只查看每个数组的长度并知道所有项目是否都是公共的。

    不幸的是,这听起来不像是一个非常现实或有用的数组,因此您要返回检查 B[] 中的 A[i]

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-11
      • 2015-07-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多