【问题标题】:O(n) Algorithm to find if 2 arrays have 2 elements that add up to a numberO(n) 算法来查找 2 个数组是否有 2 个元素加起来等于一个数字
【发布时间】:2011-11-30 07:32:43
【问题描述】:

我正在准备考试,遇到了这个似乎有点棘手的问题。

令 A[1...n] 和 B[1...n] 为 2 个整数数组,使得 A 或 B 的每个元素都在 0 到 m 的范围内,其中 m = O(n)。 (我假设这意味着 m

我们需要设计一个 O(n) 算法来找到两个元素 A[i] 和 B[j] 使得 A[i]+B[j] = 给定数 k 。如果它们不存在,我们会抛出错误消息。

现在对它们进行排序是不可能的,因为最好的排序算法是 O(n lg n) 。

也许使用哈希表 .. 或者只是创建一个长度为 m 的较小数组 X ,这样每个索引都会计算 A 中某个数字的出现次数 .. 然后我们通过 B .. 计算 diff = k - B[j] .. 并检查 X[diff] .. 如果它大于零,那么是的,它存在,然后我们可以再次通过 A 找到它的索引..

你们怎么看

【问题讨论】:

  • 可能是您实际上被允许预处理数组(花费任何时间,如O(n log n)),而O(n) 要求实际上仅适用于后续查询的不同值k?
  • 您好。你已经回答了你的问题!只是为了分箱,或者正如你所说的“或者只是创建一个更小的数组 X ...”。这将非常高效,易于实现,并且很容易看出它的运行时间是 O(n)。
  • 我意识到.. 我只是想看看互联网是否有更好的解决方案.. 但谢谢

标签: algorithm


【解决方案1】:

m = O(n) 表示mn 的常数倍数为界,不一定小于它。

你能做的就是这个。获取一个大小为k+1 的数组(所以内存O(m) 也是O(n))。将此数组称为C。将所有值初始化为未标记,假设为 -1。这是O(m),也是O(n)

现在您知道k <= 2m,因为A[i]B[i] 都是<= m。所以你遍历数组A,标记C所有k-A[i],所以C[k-A[i]] = i(如果k-A[i] >= 0假设索引从0开始)。这是O(n)。然后遍历数组B 并为每个B[j] 检查C[B[j]] 是否已经被标记。如果是这样,则C[B[j]]A 中标记某个索引,其中B[j]+A[C[B[j]]] = k。遍历B 并检查标记也是O(n)。如果找不到匹配项,则不存在这样的对。

整体算法为O(n)

这是一个例子:

n = 5
m = 15
A = [1 7 4 2 10]
B = [8 14 3 13 11]
k = 20

经过A,你会得到:

C: [-1 -1 -1 -1 -1   -1 -1 -1 -1 -1   4 -1 -1 1 -1   -1 2 -1 3 0   -1]

(间距是为了更好的可视化)然后你检查B

B[0] -> C[8] -> -1 mismatch
B[1] -> C[14] -> -1 mismatch
B[2] -> C[3] -> -1 mismatch
B[3] -> C[13] -> 1 match -> B[3] + A[1] = 20

B[3] 是 13,A[1] 是 7。

【讨论】:

    【解决方案2】:

    我们将使用一个哈希表,其中包含第一个数组中每个元素与总和之间的差异。基本上只是遍历第一个数组,计算和与数组的每个元素之间的差,并将其存储在哈希表中。然后遍历第二个数组,检查每个数字是否出现在哈希表中

    【讨论】:

      【解决方案3】:

      您可以使用您描述的哈希表方法在 O(n) 中排序(您可以只存储布尔值而不是 int,因为您只需要知道它是否存在)。一般来说,比较排序并不比 O(n lg n) 好,但如果你知道某些约束,你可以做得更好(或者如果你可以使用非比较排序,如基数排序(我认为你也可以在这里使用)) .基本上:

      1. 初始化大小为 n 的数组 A',并将所有值设置为 false。
      2. 对于 A 中的每个元素,将 A' 中的对应索引设置为 true。
      3. 对于 A' 中的每个元素,如果值为 true,则将索引附加到另一个数组 A''。
      4. A'' 现在是已排序的 A,已删除重复项。
      5. 对 B 重复。

      既然您已经对 A 和 B 进行了排序,那么问题应该很简单了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多