O(n)查找2个数组是否有2个元素加起来的算法

时间:2011-10-03 23:54:43

标签: algorithm

我正在读考试并且遇到这个看起来有点棘手的问题。

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

我们需要设计一个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找到它的索引..

你们有什么想法

3 个答案:

答案 0 :(得分:5)

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。

答案 1 :(得分:3)

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

答案 2 :(得分:1)

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

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