我正在阅读这个链接,并看到了计算可被k整除的一对数的代码。
使用了以下方法:
一种高效的方法是使用哈希技术。我们将元素分成不同的桶,具体取决于它们的(值 mod K)。当一个数被K整除时,余数可能为0、1、2、直到(k-1)。因此,我们可以采用大小为K的数组freq[](初始化为0),并增加freq[A[i]%K]的值,以便我们可以计算出在与K相除时给出余数j的值的数量。
以下是代码:
public static int countKdivPairs(int A[], int n, int K)
{
// Create a frequency array to count
// occurrences of all remainders when
// divided by K
int freq[] = new int[K];
// Count occurrences of all remainders
for (int i = 0; i < n; i++)
++freq[A[i] % K];
// If both pairs are divisible by 'K'
int sum = freq[0] * (freq[0] - 1) / 2;
// count for all i and (k-i)
// freq pairs
for (int i = 1; i <= K / 2 && i != (K - i); i++)
sum += freq[i] * freq[K - i];
// If K is even
if (K % 2 == 0)
sum += (freq[K / 2] * (freq[K / 2] - 1) / 2);
return sum;
}
我能理解代码的逐行执行过程,但我不明白代码中的逻辑是如何解决问题陈述的。
为什么我们要执行这些步骤:
1) int sum = freq[0] * (freq[0] - 1) / 2;
2) sum += freq[i] * freq[K - i];
3) if (K % 2 == 0)
sum += (freq[K / 2] * (freq[K / 2] - 1) / 2);
请您提供一份解释吗?
freq[i](记为B1)
是具有余数i
的项目数量。同样,freq[K-i](记为B2)
。现在,来自B1的每个项目都可以与来自B2的每个项目形成一对。因此,所有可能的有效配对将是|B1| x |B2|。 - Serial Lazernc2
.. 从 N 个物品中选择 2 个物品的方式数量。nc2 = n*(n-1)/2
- Serial Lazer