📌  相关文章
📜  查找所有有效对的 a[i]%a[j] 的总和(1)

📅  最后修改于: 2023-12-03 15:10:44.784000             🧑  作者: Mango

查找所有有效对的 a[i]%a[j] 的总和

在某些应用中,我们需要查找数组中所有有效对的 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] 的总和的算法,它们的时间复杂度都相对较低,可以高效地解决该问题。