leetcode
leetcode 401 ~ 450
汉明距离总和

汉明距离总和

难度:

标签:

题目描述

两个整数的 汉明距离 指的是这两个数字的二进制数对应位不同的数量。

给你一个整数数组 nums,请你计算并返回 nums 中任意两个数之间 汉明距离的总和

 

示例 1:

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

示例 2:

输入:nums = [4,14,4]
输出:4

 

提示:

  • 1 <= nums.length <= 104
  • 0 <= nums[i] <= 109
  • 给定输入的对应答案符合 32-bit 整数范围

代码结果

运行时间: 67 ms, 内存: 18.3 MB


/*
 * 思路:
 * 使用Java Stream API进行同样的操作,遍历每个二进制位,计算每个位上0和1的数量。
 * 通过Stream的map和reduce方法实现位上的0和1的计数和累加。
 */
import java.util.stream.IntStream;
 
public class Solution {
    public int totalHammingDistance(int[] nums) {
        return IntStream.range(0, 32) // 对每个二进制位进行遍历
            .map(i -> {
                int bitCount = (int) IntStream.of(nums)
                    .filter(num -> ((num >> i) & 1) == 1)
                    .count(); // 计算第i位为1的数量
                return bitCount * (nums.length - bitCount); // 计算该位的贡献
            })
            .sum(); // 总和
    }
}

解释

方法:

该题解的思路是将nums数组中所有数字转换为长度为30的二进制字符串,然后分别统计每一位上1的个数count,那么该位上0的个数就是n-count,其中n为nums数组的长度。对于任意两个数字,如果某一位一个为0一个为1,就会对汉明距离总和有1的贡献。因此每一位对总汉明距离的贡献是count*(n-count),将所有30位的贡献相加就得到了最终结果。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
为什么选择将每个整数表示为长度为30的二进制字符串,这个长度是否与具体的输入数值范围有关?
选择30位来表示每个整数是因为在标准的LeetCode问题中,整数通常是32位的有符号整数。最大的32位整数是2147483647,它的二进制表示是'01111111111111111111111111111111',这占用了31位。通常选择30位是为了确保所有的测试整数都能在这个长度内被完整表示,同时可以避免处理32位整数中的符号位。因此,这个长度与具体的输入数值范围有直接关系,确保不会因为整数的位数不足而造成信息的丢失或错误处理。
🦆
题解中提到的方法中,如何确保在将整数转换为二进制字符串时高位补零不会影响最终的汉明距离计算?
在二进制表示中,高位补零是常见的做法,用于保持所有数字的位数一致,以便进行位运算或其他处理。在汉明距离的计算中,高位的零对结果没有贡献,因为如果两个数字在某位都是0,那么在这一位的汉明距离贡献为0。因此,补零仅为了方便处理,并不会影响非零位上的汉明距离计算,保证了算法的正确性。
🦆
计算每一位的1的个数时,为什么直接使用了s[i::30].count('1'),这里的步长为30是怎么确定的?
步长为30是根据整数的二进制字符串的长度确定的。由于每个整数被转换成了30位的二进制字符串,这意味着在整个字符串s中,每个整数的对应位都是相隔30位出现的。例如,第一个整数的第一位,第二个整数的第一位,以此类推,都是按照30位的间隔排列的。因此,使用步长30可以直接索引到每一位对应的所有整数的相同位,方便统计每一位上的'1'的数量。
🦆
在这种方法中,对于每一位的0的计数为什么是通过n减去1的个数来获取,而不是直接统计0的数量?
直接统计每一位上0的数量是可行的,但在实现上,计算1的数量后直接用n减去1的数量可以更快得到0的数量,这样可以减少一次字符串遍历的成本。由于每一位上的数字只可能是0或1,所以知道了1的数量,0的数量自然是总数n减去1的数量。这种方法减少了计算量,提高了算法的效率。

相关问题

汉明距离

两个整数之间的 汉明距离 指的是这两个数字对应二进制位不同的位置的数目。

给你两个整数 xy,计算并返回它们之间的汉明距离。

 

示例 1:

输入:x = 1, y = 4
输出:2
解释:
1   (0 0 0 1)
4   (0 1 0 0)
       ↑   ↑
上面的箭头指出了对应二进制位不同的位置。

示例 2:

输入:x = 3, y = 1
输出:1

 

提示:

  • 0 <= x, y <= 231 - 1