📅  最后修改于: 2023-12-03 15:10:44.784000             🧑  作者: Mango
在某些应用中,我们需要查找数组中所有有效对的 a[i]%a[j] 的总和。这是一个常见的问题,可以用暴力枚举的方式解决,但是时间复杂度较高。本文介绍两种更优秀的解法。
考虑将 a[i]%a[j] 转化为 a[i] - k*a[j] (k 为整数),根据模运算的定义,它们的余数相同。我们可以将 a[i] % k 的余数存放在一个桶中,然后对于每个 a[j],找到余数相同的 a[i],即可计算出 a[i]%a[j] 的总和。
具体地,我们可以创建一个桶数组 b,大小为 k,对于每个 a[i],将它模 k 的余数存放在 b 数组中对应的位置。然后对于每个 a[j],找到 b 数组中和 a[j] 同余的数,假设它的下标为 idx,那么就有 idx 个数和 a[j] 满足条件。将它们求和后,加入答案中即可。
这种解法的时间复杂度为 O(n+k),其中 n 为数组大小,k 为模数,通常情况下 k 很小,因此这个算法非常高效。
下面是 Python 代码片段:
def valid_pairs_sum(a):
k = 1000000 # 模数
b = [0] * k
ans = 0
for i in range(len(a)):
r = a[i] % k
ans += b[r]
b[r] += 1
return ans
另一种解法是使用哈希表,将每个余数及其出现次数存储在哈希表中。对于每个 a[j],计算它模 k 的余数为 r,然后在哈希表中查找 r 对应的出现次数,将它们相加,即可得到 a[j] 对答案的贡献。
这种解法的时间复杂度为 O(n),但是它需要使用哈希表,因此需要额外的空间。
下面是 Python 代码片段:
def valid_pairs_sum(a):
k = 1000000 # 模数
cnt = {}
ans = 0
for i in range(len(a)):
r = a[i] % k
if r in cnt:
ans += cnt[r]
cnt[r] = cnt.get(r, 0) + 1
return ans
以上就是两种解决查找所有有效对的 a[i]%a[j] 的总和的算法,它们的时间复杂度都相对较低,可以高效地解决该问题。