我正在读考试并且遇到这个看起来有点棘手的问题。
令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找到它的索引..
你们有什么想法
答案 0 :(得分:5)
m = O(n)
表示m
以n
的常数倍为界,不一定小于它。
你能做的就是这个。获取大小为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)好,但如果你知道某些约束你可以做得更好(或者如果你可以使用非比较排序,如基数排序(我认为你也可以在这里使用)) 。基本上是:
现在你的A和B排序了,问题应该是微不足道的。