1 题目描述
2 解题思路
2.1 方法1 判断是不是整数
class Solution:
def isPowerOfTwo(self, n: int) -> bool:
if(n<=0):
return False
if(n&(n-1)==0):
return True
return False
2.2 方法2 一直除2
如果n被2整除,就将n除2,看最后不能被2整除的时候,结果是否为1
class Solution:
def isPowerOfTwo(self, n: int) -> bool:
if(n<=0):
return False
while(n%2==0):
n=n//2
return(n==1)
2.3 方法3 x & (-x)
x & (-x) 可以获取到二进制中最右边的 1,且其它位设置为 0
在补码表示法中,−x=¬x+1。换句话说,要计算 −x,要将 x 所有位取反再加 1。
在二进制表示中,¬x+1 表示将该 1 移动到¬x 中最右边的 0 的位置上,并将所有较低的位设置为 0。而¬x 最右边的 0 的位置对应于 x 最右边的 1 的位置。
总而言之,−x=¬x+1,此操作将 x 所有位取反,但是最右边的 1 除外。
因此,x 和−x 只有一个共同点:最右边的 1。这说明 x & (-x) 将保留最右边的 1。并将其他的位设置为 0。
2 的幂在二进制中是有一个 1 后跟一些0
不是 2 的幂的二进制中有一个以上的 1
我们通过 x & (-x) 保留了最右边的 1,并将其他位设置为 0
若 x 为 2 的幂,则它的二进制表示中只包含一个 1,则有 x & (-x) = x。
若 x 不是 2 的幂,则在二进制表示中存在其他 1,因此 x & (-x) != x。
因此判断是否为 2 的幂的关键是:判断 x & (-x) == x。
class Solution:
def isPowerOfTwo(self, n: int) -> bool:
if(n<=0):
return False
tmp=n&(-n)
return(tmp==n)
2.4 布莱恩-科尼根算法
当我们在number和number-1上做and位运算的时候,原数字最右边等于1的那一比特会被移除.
(number- 1) 代表了将 number 最右边的 1 设置为 0,并且将较低位设置为 1。
再使用与运算:则 x 最右边的 1 和就会被设置为 0,因为 1 & 0 = 0。
- 2 的幂二进制表示只含有一个 1。
- x & (x - 1) 操作会将 2 的幂设置为 0,因此判断是否为 2 的幂是:判断 x & (x - 1) == 0
class Solution: def isPowerOfTwo(self, n: int) -> bool: if(n<=0): return False if(n&(n-1)==0): return True return False
2.5 2^32的约数
由于这边题目里说了,所以n最大不会超过2^32
如果n是2的幂,那么它必然是2^32的约数,所以只需要判断2^32能否整除n即可
class Solution:
def isPowerOfTwo(self, n: int) -> bool:
if(n<=0):
return False
tmp=pow(2,32)
if(tmp%n==0):
return True
return False