题目
给你一个整数 ,请你判断该整数是否是
的幂次方。如果是,返回
true
;否则,返回 false
。
如果存在一个整数 使得
,则认为
是
的幂次方。
示例 1:
- 输入:
n = 1
- 输出:
true
- 解释:
= 1
示例 2:
- 输入:
n = 16
- 输出:
true
- 解释:
= 16
示例 3:
- 输入:
n = 3
- 输出:
false
示例 4:
- 输入:
n = 4
- 输出:
true
方法一:二进制表示
思路及解法
一个数 是 2 的幂,当且仅当
是正整数,并且
的二进制表示中仅包含 1 个 1。
因此我们可以考虑使用位运算,将 的二进制表示中最低位的那个 1 提取出来,再判断剩余的数值是否为 0 即可。下面介绍两种常见的与「二进制表示中最低位」相关的位运算技巧。
第一个技巧是
其中 表示按位与运算。该位运算技巧可以直接将
二进制表示的最低位
移除,它的原理如下:
假设
的二进制表示为
,其中
表示若干个高位,
表示最低位的那个 1,
表示后面的若干个
,那么
的二进制表示为:
我们将
与
进行按位与运算,高位
不变,在这之后的所有位都会变为
,这样我们就将最低位的那个
移除了。
因此,如果 是正整数并且
,那么
就是
的幂。
第二个技巧是
其中 是
的相反数,是一个负数。该位运算技巧可以直接获取
二进制表示的最低位的
。
由于负数是按照补码规则在计算机中存储的, 的二进制表示为
的二进制表示的每一位取反再加上
,因此它的原理如下:
假设
的二进制表示为
,其中
表示若干个高位,
表示最低位的那个
,
表示后面的若干个
,那么
的二进制表示为:
其中
表示将
每一位取反。我们将
与
进行按位与运算,高位全部变为
,最低位的
以及之后的所有
不变,这样我们就获取了
二进制表示的最低位的
。
因此,如果 是正整数并且
,那么
就是
的幂。
代码
class Solution {
func isPowerOfTwo(_ n: Int) -> Bool {
return n > 0 && (n & (n - 1)) == 0
}
}
class Solution {
func isPowerOfTwo(_ n: Int) -> Bool {
return n > 0 && (n & -n) == n
}
}
复杂度分析
-
时间复杂度:
。
-
空间复杂度:
。
方法二:判断是否为最大 2 的幂的约数
思路及解法
除了使用二进制表示判断之外,还有一种较为取巧的做法。
在题目给定的 位有符号整数的范围内,最大的
的幂为
。我们只需要判断
是否是
的约数即可。
代码
class Solution {
func isPowerOfTwo(_ n: Int) -> Bool {
let BIG = 1 << 30
return n > 0 && BIG % n == 0
}
}
复杂度分析
-
时间复杂度:
。
-
空间复杂度:
。
网友评论