题目描述
给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false 。
如果存在一个整数 x 使得 n == 2x ,则认为 n 是 2 的幂次方。
示例 1:
输入:n = 1
输出:true
解释:20 = 1
示例 2:
输入:n = 16
输出:true
解释:24 = 16
示例 3:
输入:n = 3
输出:false
示例 4:
输入:n = 4
输出:true
示例 5:
输入:n = 5
输出:false
提示:
-2^31 <= n <= 2^31 - 1
题解
思路1:辗除法
static public func isPowerOfTwo1(_ n:Int) -> Bool {
var n = n
while n>0 && n%2==0 {
n = n/2
}
return n==1
}
思路2:二进制表示 n & (n - 1) == 0
一个数n 是2 的幂,当且仅当n是正整数,并且n的二进制表示中仅包含1个1
位运算技巧n&(n-1),该位运算技巧可以直接将n二进制表示的最低位1移除
假设n的二进制表示为(a10⋯0)2,其中a表示若干个高位,1表示最低位的那个1,0⋯0 表示后面的若干个0,那么n−1 的二进制表示为:(a01⋯1)2
我们将(a10⋯0)2与(a01⋯1)2 进行按位与运算,高位a不变,在这之后的所有位都会变为0,这样我们就将最低位的那个1移除了
n & (n - 1) == 0,则表示n为2的幂
static public func isPowerOfTwo2(_ n:Int) -> Bool {
return n>0 && (n&(n-1)==0)
}
思路3:二进制表示 n & (-n) == n
一个数n 是2 的幂,当且仅当n是正整数,并且n的二进制表示中仅包含1个1
位运算技巧n&(-n),该位运算技巧可以直接获取n二进制表示的最低位的1
由于负数是按照补码规则在计算机中存储的,−n 的二进制表示为n的二进制表示的每一位取反再加上1,因此它的原理如下:
假设n的二进制表示为(a10⋯0)2,其中a表示若干个高位,1表示最低位的那个1,0⋯0 表示后面的若干个0,那么−n 的二进制表示为:
(b01⋯1)2 + (1)2 = (b10⋯0)2,
其中b表示将a每一位取反。我们将(a10⋯0)2与(b10⋯0)2进行按位与运算,高位全部变为0,最低位的1以及之后的所有0不变,这样我们就获取了n二进制表示的最低位的1。
n & (-n) == n,则表示n为2的幂
static public func isPowerOfTwo3(_ n:Int) -> Bool {
return n>0 && (n&(-n)==n)
}
思路4:判断是否为最大2的幂的约数
在题目给定的32位有符号整数的范围内,最大的2 的幂为 2^30 = 1073741824。我们只需要判断n 是否是2^30的约数即可
static public func isPowerOfTwo4(_ n:Int) -> Bool {
let big = 1<<30
return n>0 && (big%n == 0)
}
参考:https://leetcode-cn.com/problems/power-of-two
https://leetcode-cn.com/problems/power-of-two/solution/2de-mi-by-leetcode-solution-rny3/