二进制相关问题
本文探索二进制相关题目,主要包括leetcode
- 461.汉明距离
- 136.只出现一次的数字
- 191.位1的个数
- 338.比特位计数
1.汉明距离
两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目。解题思路是对两个数字进行异或(异或:相同为0不同为1),统计异或后1的个数就是汉明距离。
def hammingDistance(x, y):
tmp = x ^ y
distance = 0
while tmp:
if tmp%2: #判断异后的数字最后一位是不是1,也可写成(tmp&1)
distance += 1
tmp >>= 1 #将最后一位右移
return distance
2.只出现一次的数字
此题只要记住任何数和0异或都是原来的数:a^0=a;任何数和自己异或都是0。
def singleNumber(nums):
a = 0
for num in nums:
a = a ^ num
return a
最后剩下的就是只出现一次的数字。
3.位1的个数
该题与汉明距离比较相似,不需要做异或,直接判断最后一位是否为1和右移即可。
def hammingWeight(n):
res = 0
while n:
if n&1 == 1:
res += 1
n >>= 1
return res
4.比特位计数
比特位计数是对0 ≤ i ≤ num范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。最直观的思路是每个数字都去计算一遍它的二进制中1的个数。
def countBits(num):
def count1(num):
if num == 0: return 0
ans = 0
while num:
if num%2:
ans += 1
num >>= 1
return ans
res = []
for i in range(num+1):
res.append(count1(i))
return res
其时间复杂度是O(N2),是可以继续优化的。优化思路如下:
- 奇数一定比偶数多一:如00,01,10,11;
- 偶数中 1 的个数一定和除以 2 之后的那个数一样多,因为偶数的最后一位为0,除以2相当于右移一位,如2:0010,4:0100。
这样就是一个选择问题,我们根据奇偶性遍历。
def countBits(num):
dp = [0]*(num+1)
dp[0] = 0
for i in range(1, num+1):
if i%2 != 0:
dp[i] = dp[i-1]+1
else:
dp[i] = dp[i//2]
return dp