【力扣题】题目描述:
【Python3】代码:
1、解题思路:将整数转为二进制字符串,截取、反转、补足32位,再转回整数。
知识点:bin(...):转为二进制字符串,即‘0bxx...’。
str [2:]:切片,从第2位开始截取字符串。
str [::-1]:反转字符串,即第1个变成最后一个,第2个变成倒数第2个,...。
str.ljust(...):左对齐,并指定字符补足右边空缺位数。
int(...):转为整数。
另:str.replace(old,new):字符串中用new替换old。
str1+str2:字符串拼接。(例如:“1”+“2”=“12”)
len(str):获取字符串长度。
class Solution:
def reverseBits(self, n: int) -> int:
return int(bin(n)[2:][::-1].ljust(32,'0'),2)
# 或者
return int(bin(n).replace("0b","")[::-1].ljust(32,'0'),2)
# 或者
return int((bin(n)[2:][::-1]+"0"*32)[:32],2)
# 或者
a = bin(n).replace("0b","")[::-1]
m = 32 - len(a)
for i in range(m):
a += "0"
return int(a,2)
2、解题思路:位移。将二进制从低到高依次枚举每一位,反转到对应位置(例如:最低位反转到最高位)。
知识点:n & 1:获取二进制低位的一位。整数n和1进行二进制与运算。(二进制中,1&1=1,1&0=0,0&0=0)
res |= x:res和x进行二进制或运算,并重新赋值给res。
<< (31-i):左移(31-i)位。例如:第0位左移到第31位。
n >>= 1:n右移一位,并重新赋值给n。
另:range(31,-1,-1): 从31到0的数组(含31不含-1)。即依次31、30、29、...2、1、0。
class Solution:
def reverseBits(self, n: int) -> int:
res = 0 #记录反转结果
for i in range(32):
res |= (n & 1) << (31-i)
n >>= 1
return res
# 或者
res = 0
for i in range(31,-1,-1):
res |= (n & 1) << i
n >>= 1
return res
3、解题思路:分治算法。将32位分成两个16位,16位再分成两个8位,...,2位最后分成两个1位。再回溯反转合并,两个1位反转合并成2位,两个2位再反转合并成4位,...,两个16位最后反转合并成32位。
知识点:二进制与运算:1&1=1,1&0=0,0&0=0。和0与都为0,和1与都为自身。
二进制或运算:1 | 1=1,1 | 0=1,0 | 0=0。
python里不对位数做限制,所以左移后必须“与” 一个0xffffffff ,表示只取32位。
注解:0x55555555即01010101...01010101。左移1位再和其“与”运算,和其“与”运算再右移1位,相当于两个1位互换位置。
0x33333333即00110011...00110011。左移2位再和其“与”运算,和其“与”运算再右移2位,相当于两个2位互换位置。
0x0f0f0f0f、0x00ff00ff 同理。
class Solution:
def reverseBits(self, n: int) -> int:
# python里不对位数做限制,所以左移后必须“与” 一个0xffffffff ,表示只取32位
M32 = 0xffffffff # 11111111...11111111,即1*32
M1 = 0x55555555 # 01010101...01010101
M2 = 0x33333333 # 00110011...00110011
M4 = 0x0f0f0f0f # 00001111...00001111
M8 = 0x00ff00ff # 00000000...11111111
n = (n >> 1) & M1 | ((n & M1) << 1) & M32
n = (n >> 2) & M2 | ((n & M2) << 2) & M32
n = (n >> 4) & M4 | ((n & M4) << 4) & M32
n = (n >> 8) & M8 | ((n & M8) << 8) & M32
return n >> 16 | (n << 16) & M32