231. 2 的幂
题目描述
给你一个整数 n,请你判断该整数是否是 2 的幂次方。如果是,返回 true ;否则,返回 false 。
如果存在一个整数 x 使得 n == 2x ,则认为 n 是 2 的幂次方。
提示:
- − 2 31 < = n < = 2 31 − 1 -2^{31} <= n <= 2^{31} - 1 −231<=n<=231−1
暴力
写法1:乘法
思路:
- 依次枚举,直至 c n t > = n cnt >= n cnt>=n
注意:
- 使用
long
防止 c n t cnt cnt 在int溢出
class Solution {
public boolean isPowerOfTwo(int n) {
long cnt = 1;
while (cnt <= n) {
if (cnt == n) return true;
cnt *= 2L;
}
return false;
}
}
- 时间复杂度: O ( l o g n ) O(logn) O(logn)
- 空间复杂度:
O
(
1
)
O(1)
O(1)
写法2:除法
- 使用除法时,不必像上麦那个 “乘法” 中单独开一个
long
变量,直接对n /= 2;
,并判断该过程中n
是否会变成“奇数”,即可。
class Solution {
public boolean isPowerOfTwo(int n) {
if (n < 0) return false;
while (n > 0) {
// 单独处理
if (n == 1) return true;
// 遇到奇数,则gg
if ((n & 1) == 1) {
return false;
}
n >>= 1;
}
return false;
}
}
- 时间复杂度: O ( l o g n ) O(logn) O(logn)
- 空间复杂度: O ( 1 ) O(1) O(1)
位运算 - 解法1 😄
思路 🤔
- 奇数、负数、0,必然不满足题意;
n == 1
为 2 0 2 ^ 0 20 单独处理之;- 由于
(
2
n
−
1
)
(2^{n-1})
(2n−1) 对应的二进制都是
(
111..1
)
2
(111..1)_2
(111..1)2,所以要判断
n
是否为 2 n 2^n 2n,则可以通过判断(n - 1)
是否等于 2 n − 1 2^{n - 1} 2n−1 来进行- 即, 只要
(n - 1)
对应的二进制中一旦出现了0
,则说明n
不是 2的次幂
- 即, 只要
class Solution {
public boolean isPowerOfTwo(int n) {
// 奇数、负数、0,直接g
if (n <= 0) return false;
// 单独处理
if (n == 1) return true;
// (2^n-1)对应的二进制都是 11..1
n--;
while (n > 0) {
// 只要(n - 1)对应的二进制中出现了0,则说明g
if ((n & 1) == 0) {
return false;
}
n >>= 1;
}
return true;
}
}
- 时间复杂度:
O
(
32
)
O(32)
O(32) (即,
n
n
n 对应的二进制位数,
int
32 bit) - 空间复杂度: O ( 1 ) O(1) O(1)
位运算-解法2 ⭐️ 🔥
思路:🤔
-
2
2
2 的次幂(指数函数)一定大于0,所以
非正数
一定不可能为2的次幂… - 对于
正整数
而言:-
2
n
2^n
2n 的次幂转换为二进制后,一定是形式为:
第一位为1,后n位均为1
,即 1000..000 1000..000 1000..000形式; -
2
n
−
1
2^n-1
2n−1的次幂转换为二进制后,一定是形式为:
所有的n-1位均为1
,即 111...1 111...1 111...1 形式; - 所以,当 2 n 2^{n} 2n& 2 n − 1 = = 0 2^{n-1}==0 2n−1==0 时,表示 n u m s nums nums 为2的次幂;否则,则不是。
-
2
n
2^n
2n 的次幂转换为二进制后,一定是形式为:
例如 🌰
- 当 n u m s = 8 nums=8 nums=8时,其二进制为 1000 1000 1000; n u m s − 1 = 7 nums-1=7 nums−1=7,其二进制为 111 111 111,即 2 n 2^{n} 2n& 2 n − 1 = = 0 2^{n-1}==0 2n−1==0,所以8是2的次幂;
- n u m s = 7 nums=7 nums=7,其二进制为 111 111 111; n u m s − 1 = 6 nums-1=6 nums−1=6,其二进制为 110 110 110,即 2 n 2^{n} 2n& 2 n − 1 = = 1 2^{n-1}==1 2n−1==1,不是2的次幂。
class Solution {
public boolean isPowerOfTwo(int n) {
// 次幂(指数函数)一定大于0,所以非正数一定不可能为2的次幂...
if (n <= 0) return false;
// 正整数
return (n & (n - 1)) == 0;
}
}
- 时间复杂度: O ( 1 ) O(1) O(1)
- 空间复杂度: O ( 1 ) O(1) O(1)