问题描述
给出N个整数。一个三元组数字是一组三个数字,它们的和可被常数M整除。从给定的N个整数中找出多少个不同的三元组数字的和可被M整除。 找到该问题答案的最佳算法是什么?
请注意:无论其实际值如何,每个元素都会被视为不同。
This is the link to the actual problem
解决方法
有一个O(N + M ^ 2)解决方案。
首先创建一个数组C [M],其中C [i]包含为i mod M的输入数字的数量。这需要O(N)时间。
然后对于每个i
我们可以通过在i和j上循环并找到导致和为0(模M)的唯一k来有效地做到这一点,如果k 这是完整的代码,可以为给定的测试用例生成正确的答案26:def choose2(n):
return n * (n-1) // 2
def choose3(n):
return n * (n-1) * (n-2) // 6
def triples(A,M):
C = [0] * M
for a in A:
C[a % M] += 1
T = 0
for i in range(M):
for j in range(i,M):
k = (-i - j) % M
if k < j:
continue
if i == j == k:
T += choose3(C[i])
elif i == j:
T += choose2(C[i]) * C[k]
elif j == k:
T += C[i] * choose2(C[j])
else:
T += C[i] * C[j] * C[k]
return T
print(triples([1,10,4,3,2,5,1,9,5],5))
在将每个数字除以M后,我将首先为每个数字计算remainder,然后将所有N个数字除以它们的余数。
这是N * log(N)费用。
然后对于每对数字,如果所有数字之间都有匹配的余数,我将进行搜索,这将使我的总和被M整除。
有N ^ 2对,每个查找都是二进制搜索-log(N)。
所以我看到解决方案的成本为N ^ 2 * log(N),但是也许有一种更复杂,更便宜的解决方案。