1 题目描述
2 解题思路
2.1 暴力两两比较
两个数字之间的汉明距离可以使用 文巾解题 461. 汉明距离_刘文巾的博客-CSDN博客 中的任何一种方法,但是因为这个是两两比较,时间复杂度比较高,所以提交后会超时。
class Solution:
def totalHammingDistance(self, nums: List[int]) -> int:
ret=0
l1=len(nums)
for i in range(l1):
for j in range(i+1,l1):
tmp=nums[i]^nums[j]
ret+=bin(tmp).count('1')
return(ret)
2.2 逐位统计
在计算汉明距离时,我们考虑的是同一比特位上的值是否不同,而不同比特位之间是互不影响的。
对于数组nums 中的某个元素val,若其二进制的第 i 位为 1,我们只需统计nums 中有多少元素的第 i 位为 0,即计算出了val 与其他元素在第 i 位上的汉明距离之和。(因为1和1是没有汉明距离的,同时我们不用考虑二进制的第i位为0的情况。因为为0的所有情况都在考虑第i位为1的时候考虑过了。)
具体地,若长度为 n 的数组nums 的所有元素二进制的第 i 位共有 c 个 1,那么就有n−c 个 0。那么者些元素在二进制的第 i 位上的汉明距离之和为 c*(n-c)。
我们可以从二进制的最低位到最高位,逐位统计汉明距离。将每一位上得到的汉明距离累加即为答案。
由于题目说了最大的数为,最小的比这个数大的的2的幂就是
,所以我们最多就考虑这30位就ok了。
class Solution:
def totalHammingDistance(self, nums: List[int]) -> int:
n=len(nums)
ret=0
for i in range(30):
c=0
for j in nums:
c+=(j>>i)&1
ret+=c*(n-c)
return(ret)