位运算:
二进制位运算主要有三种:
一. 1 & 0= 0,1 & 1= 1,0 & 0= 0
第一种与运算,即当两者皆为1时结果为1,否则结果为0。
二. 1 | 1=1,1 | 0 = 1,0 | 0 = 0
第二种或运算,即当两者有1时结果就为1,否则结果为0。
三. 1 ^ 0 = 1, 1 ^ 1 = 0 , 0 ^ 0 = 0
第三种抑或运算,即当两者相异时,结果为1,否则为0。
位运算特性:a ^ 0 = a , a ^ a = 0,
a & (a-1)(去除a的最后一位1)
汉明距离问题
汉明重量:一组数中1的个数,如10011的汉明重量为3
汉明距离:两个数中相异位数的个数,如10110与11001的汉明距离为4
例题:
1.汉明距离
问题描述:两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目。
给出两个整数 x 和 y,计算它们之间的汉明距离。
示例:
输入: x = 1, y = 4
输出: 2
解释:
1 (0 0 0 1)
4 (0 1 0 0)
↑ ↑
上面的箭头指出了对应二进制位不同的位置。
思路:可先对两个数字进行抑或的位运算,由于抑或运算的性质,两数字相异的位数都变为了1,这时计算结果的1的个数即为两数的汉明距离。
代码实现:
def hammingLength(x,y):
new = x ^ y
count = 0
while new != 0:
new = new & (new - 1)
count+=1
return count
2.汉明距离总和
问题描述:两个整数的 汉明距离 指的是这两个数字的二进制数对应位不同的数量。
计算一个数组中,任意两个数之间汉明距离的总和。
示例:
输入: 4, 14, 2
输出: 6
解释: 在二进制表示中,4表示为0100,14表示为1110,2表示为0010。(这样表示是为了体现后四位之间关系)
所以答案为:
HammingDistance(4, 14) + HammingDistance(4, 2) + HammingDistance(14, 2) = 2 + 2 + 2 = 6.
思路:
设最高位数为32位,外层循环为循环32次,内层循环循环给定的列表。设置res储存最后的结果。内层设置两个计数器分别计算1和0的个数,内层循环开始先将数向右移动i位(i位外层当前循环的次数),接着将当前的数与1进行与运算,根据与运算的性质,最后一位为1结果就是1,否则结果就为0。遍历所有数后计数器储存当前位数的0和1的个数。这时当前位数两两的汉明距离总和就为两个计数器相乘。将这个结果储存到最后的结果中,并开始下一次循环。最后输出res。
代码实现:
def hammingLengthSum(List):
res=0
for i in range(32):
count_0=0
count_1=0
for j in list:
if (j>>i) & 1 :
count_1+=1
else:
count_0+=1
res=res+count_1*count_0
return res
3.只出现一次的数字
问题描述:给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
示例:
输入: [2,2,1]
输出: 1
输入: [4,1,2,1,2]
输出: 4
思路:根据抑或运算的性质,a ^ 0 = a, a ^ a = 0 ,b ^ (a ^ b) = a。
代码实现:
def singleNum(List):
res=0
for i in List:
res = res ^ i
return res