我刚刚发现如何在O(n^2 log n)
时间内解决这个问题(假设每个数组的长度相同):
for each A[i]:
for each B[j]:
if A[i] + B[j] + C.binarySearch(S - A[i] - B[j]) == S:
return (i, j, k)
有没有办法在O(n^2)
时间内解决这个问题或改进上述算法?
答案 0 :(得分:0)
你拥有的算法也不错。相对于n^2
,log(n)
增长得如此之慢,以至于它实际上可以被视为常数。例如,n = 1000000
,n^2 = 1000000000000
和log(n) = 20
。一旦n
变得足够大以使log(n)
产生任何重大影响,n^2
已经非常大,无论如何都无法计算结果。
一个灵感来自@YvesDaoust的解决方案,虽然我不确定它是否完全相同:
A[i]
,计算余额R = S - A[i]
,该余数应为某些B[j]
和C[k]
的组合; j = 0
和k = |C|-1
(C
中的最后一个索引); B[j] + C[k] < R
,请增加j
; B[j] + C[k] > R
,请减少k
; B[j] + C[k] = R
或j >= |B|
或k < 0
我建议不要使用微优化过多地使算法复杂化。对于任何相当小的数字组合,它将足够快。如果阵列对于这种方法而言变得太大,那么你的问题就会成为Hill Climbing等机器学习方法的理想选择。
答案 1 :(得分:0)
O(N²)
解决方案非常简单。
首先考虑两个数组的情况,找到A[i] + B[j] = S'
。
这可以改写为A[i] = S' - B[j] = B'[j]
:您需要在两个排序的数组中找到相等的值。这可以通过合并过程在线性时间内完成。 (您可以显式计算数组B'
,但这是不必要的,只需动态执行:而不是获取B'[j]
,获取S' - B[NB-1-j]
)。
建立此程序后,只需将C
的所有元素用于搜索S - C[k]
即可。
这是执行该操作的Python代码并报告所有解决方案。 (它已被重写为紧凑和对称。)
for k in range(NC):
# Find S - C[k] in top-to-tail merged A and B
i, j= 0, NB - 1
while i < NA and 0 <= j:
if A[i] + B[j] + C[k] < S:
# Move forward A
i+= 1
elif A[i] + B[j] + C[k] > S:
# Move back B
j-= 1
else:
# Found
print A[i] + B[j] + C[k], "=", A[i], "+", B[j], "+", C[k]
i+= 1; j-= 1
执行
A= [1, 2, 3, 4, 5, 6, 7]; NA= len(A)
B= [2, 3, 5, 7, 11]; NB= len(B)
C= [1, 1, 2, 3, 5, 7]; NC= len(C)
S= 15
给出
15 = 3 + 11 + 1
15 = 7 + 7 + 1
15 = 3 + 11 + 1
15 = 7 + 7 + 1
15 = 2 + 11 + 2
15 = 6 + 7 + 2
15 = 1 + 11 + 3
15 = 5 + 7 + 3
15 = 7 + 5 + 3
15 = 3 + 7 + 5
15 = 5 + 5 + 5
15 = 7 + 3 + 5
15 = 1 + 7 + 7
15 = 3 + 5 + 7
15 = 5 + 3 + 7
15 = 6 + 2 + 7
答案 2 :(得分:0)
如果阵列是非负数的话
*您可以将所有3个数组修剪为S =&gt; A[n] > S
*类似地,如果A [aIdx] + B [bIdx]&gt;不打扰检查阵列C.小号
答案 3 :(得分:0)
制备
+O(N.log(n))
?O(log(N))
计算:
i=bin_search(smallest i that A[i]+B[0]+C[0]>=S); for (;i<Na;i++) { if (A[i]+B[0]+C[0]>S) break;
j=bin_search(smallest j that A[i]+B[j]+C[0]>=S); for (;j<Nb;j++) { if (A[i]+B[j]+C[0]>S) break;
ss=S-A[i]-B[j];
if (ss<0) break;
k=bin_search(ss);
if (k found) return; // found solution is: i,j,k
}
}
如果我看对了,请N=max(Na,Nb,Nc)
,M=max(valid intervals A,B,C)
... M<=N
(3*N.log(N)+log(N)+M*log(N)*M*log(N)) -> O((M^2)*log(N))
M<<N