【LeetCode-位运算】汉明距离总和

题目描述

两个整数的 汉明距离 指的是这两个数字的二进制数对应位不同的数量。
计算一个数组中,任意两个数之间汉明距离的总和。

示例:

输入: 4, 14, 2

输出: 6

解释: 在二进制表示中,4表示为0100,14表示为1110,2表示为0010。(这样表示是为了体现后四位之间关系)
所以答案为:
HammingDistance(4, 14) + HammingDistance(4, 2) + HammingDistance(14, 2) = 2 + 2 + 2 = 6.

注意:

  • 数组中元素的范围为从 0到 10^9。
  • 数组的长度不超过 10^4。

题目链接: https://leetcode-cn.com/problems/total-hamming-distance/

思路1

使用两层循环计算任意两个数之间的汉明距离,将任意两个数字的汉明距离相加就是答案。

class Solution {
public:
    int totalHammingDistance(vector<int>& nums) {
        int ans = 0;
        for(int i=0; i<nums.size(); i++){
            for(int j=i+1; j<nums.size(); j++){
                int t = nums[i]^nums[j];
                int cnt = 0;
                while(t){
                    if(t&1) cnt++;
                    t = t>>1;
                }
                ans += cnt;
            }
        }
        return ans;
    }
};
//超时

该方法超时。

  • 时间复杂度:O(n^2)
  • 空间复杂度:O(1)

思路2

每个 int 都是 32 位的,我们可以纵向比较所有数字的二进制位。假设当前比较的是第 i 位,有 pos 个数字第 i 位为 1,有 neg 个数字第 i 位为 0,则该位的汉明距离之和为 pos*neg。遍历数字的每一位,将每一位的汉明距离之和加起来就是最终的答案。

class Solution {
public:
    int totalHammingDistance(vector<int>& nums) {
        int ans = 0;
        for(int i=0; i<32; i++){
            int pos = 0;
            int neg = 0;
            for(int j=0; j<nums.size(); j++){
                if(nums[j]&1) pos++;
                else neg++;
                nums[j] = nums[j]>>1;
            }
            ans += pos*neg;
        }
        return ans;
    }
};
  • 时间复杂度:O(32*n) = O(n)
  • 空间复杂度:O(1)
posted @ 2021-01-08 16:12  Flix  阅读(162)  评论(0编辑  收藏  举报