[Leetcode] 477. Total Hamming Distance 解题报告

本文介绍了一种计算一组整数间所有配对的总哈明距离的方法。通过两种不同的算法实现——暴力计算法和按位统计法,并给出了具体的示例说明。

题目

The Hamming distance between two integers is the number of positions at which the corresponding bits are different.

Now your job is to find the total Hamming distance between all pairs of the given numbers.

Example:

Input: 4, 14, 2

Output: 6

Explanation: In binary representation, the 4 is 0100, 14 is 1110, and 2 is 0010 (just
showing the four bits relevant in this case). So the answer will be:
HammingDistance(4, 14) + HammingDistance(4, 2) + HammingDistance(14, 2) = 2 + 2 + 2 = 6.

Note:

  1. Elements of the given array are in the range of to 10^9
  2. Length of the array will not exceed 10^4.

思路

1、暴力计算法:计算nums中每个pair中的Hamming距离,将和加起来即可。显然这种暴力法只能用来热身,过不了大数据测试。

2、按位统计法:注意到Hamming距离计算中,只有同一位置上的bit才会产生距离,所以我们可以统计nums中,32个位置上分别有多少个1和多少个0。假设在第i位有m个1和n个0,那么该位上贡献的Hamming距离就是m * n。最终将32个位上的贡献值加起来即可。

代码

1、暴力统计法:

class Solution {
public:
    int totalHammingDistance(vector<int>& nums) {
        int ret = 0;
        for (int i = 0; i < nums.size(); ++i) {
            for (int j = i + 1; j < nums.size(); ++j) {
                ret += hammingDistance(nums[i], nums[j]);
            }
        }
        return ret;
    }
private:
    int hammingDistance(int a, int b) {
        int c = a ^ b, ans = 0;
        while (c != 0) {
            ans += c & 1;
            c >>= 1;
        }
        return ans;
    }
};

2、按位统计法:

class Solution {
public:
    int totalHammingDistance(vector<int>& nums) {
        if (nums.size() == 0) {
            return 0;
        }
        vector<int> zeros(32, 0), ones(32, 0);
        for (auto num : nums) {
            for (int i = 0; i < 32; ++i) {
                if ((num >> i) & 1) {
                    ++ones[i];
                }
                else {
                    ++zeros[i];
                }
            }
        }
        int ans = 0;
        for (int i = 0; i < 32; ++i) {
            ans += zeros[i] * ones[i];
        }
        return ans;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值