4

我开始准备面试,遇到了这个问题:

  • 给出一个整数数组
  • 现在以二进制表示形式计算数组中所有整数对的汉明距离之和。

例子:

given {1,2,3} or {001,010,011} (used 3 bits just to simplify)
result= HD(001,010)+HD(001,011)+HD(010,011)= 2+1+1=4;

唯一的优化,来自纯粹的蛮力解决方案,我知道我可以在这里使用,是在汉明距离的单独计算中,如下所示:

int hamming_distance(unsigned x, unsigned y)
{
    int       dist;
    unsigned  val;

    dist = 0;
    val = x ^ y;    // XOR

    // Count the number of bits set
    while (val != 0)
    {
        // A bit is set, so increment the count and clear the bit
        dist++;
        val &= val - 1;
    }

    // Return the number of differing bits
    return dist;
}

解决这个问题的最佳方法是什么?

4

2 回答 2

4

这是我的 C++ 实现,具有 O(n) 复杂度和 O(1) 空间。

int sumOfHammingDistance(vector<unsigned>& nums) {
    int n = sizeof(unsigned) * 8;
    int len = nums.size();
    vector<int> countOfOnes(n, 0);
    for (int i = 0; i < len; i++) {
        for (int j = 0; j < n; j++) {
            countOfOnes[j] += (nums[i] >> j) & 1;
        }
    }
    int sum = 0;
    for (int count: countOfOnes) {
        sum += count * (len - count);
    }
    return sum;
}
于 2016-02-16T00:29:27.697 回答
3

您可以单独考虑位位置。这给了你 32 个(或其他一些)更简单的问题,你仍然需要计算所有汉明距离对的总和,除了现在它超过 1 位数字。

两个 1 位数字之间的汉明距离是它们的 XOR。

现在它已经成为这个问题的最简单的例子——它已经按位分割了。

所以为了重申这个问题的答案,你取一个位,计算 0 的数量和 1 的数量,将它们相乘以获得这个位的贡献。对所有位位置求和。它甚至比链接问题更简单,因为在这个问题中每一位的贡献权重都是 1。

于 2015-01-22T19:19:11.703 回答