【力扣LeetCode】231_2的幂(法1:循环迭代,法2:位运算)
- 第 138 篇 -
Date: 2025 - 09 - 26
Author: 郑龙浩(仟墨)
文章目录
- 【力扣LeetCode】231_2的幂
- 方法1:
- 方法2:
- 两种方法代码实现:
【力扣LeetCode】231_2的幂
方法1:
算法:循环迭代
思考:
写一个循环,循环的过程是不断的/2,如果除的开,就可以继续/2,如果除不开,就证明不是2的倍数
直到循环到1的时候,就证明是2的次幂
具体过程:
-
先特判:如果 n小于1,直接false,因为2的幂次不可能 ≤0。
-
循环干它:只要 n还比1大,就继续循环除以2:
- 如果能整除(n % 2 == 0),就继续除。
- 如果除不开(n % 2 != 0),直接判定不是2的幂次(false)
-
最终结果:如果 n被除到1了,说明它就是2的幂次(true)
方法2:
算法:位运算
原理:2的幂的二进制的共同特征为:仅最高位是 1,其余全为 0,相当于1后面跟的全部是0
判断原理:用 n & (n - 1)消去最低位的1,如果能抵消得出的是0,那么就是2的幂
- 如果是2的幂:8 & 7 → 1000 & 0111 = 0000
- 如果不是2的幂:6 & 5 → 0110 & 0101 = 0100
代码过程:
- 特判:如果n <= 0,直接返回false,因为2的幂都是正数
- 关键操作:使用n & (n - 1)来消除最低位的1
如果n是2的幂,那么n & (n - 1)的结果会是0, 例如:8 & 7 → 1000 & 0111 = 0000 - 返回结果:如果结果为0,则是2的幂,否则不是
两种方法代码实现:
// 231_2的幂
// Author: 郑龙浩 Date: 2025年09月25日// 方法1:// 算法:循环迭代
// 思路:
// 写一个循环,循环的过程是不断的/2,如果除的开,就可以继续/2,如果除不开,就证明不是2的倍数
// 直到循环到1的时候,就证明是2的次幂// 1 先特判:如果 n小于1,直接false,因为2的幂次不可能 ≤0。
// 2 循环干它:只要 n还比1大,就继续循环除以2:
// 如果能整除(n % 2 == 0),就继续除。
// 如果除不开(n % 2 != 0),直接判定不是2的幂次(false)
// 3 最终结果:如果 n被除到1了,说明它就是2的幂次(true)
#include "bits/stdc++.h"
using namespace std;class Solution {
public:bool isPowerOfTwo(int n) {// 特判:如果输入的是<1的数字,但并不是2的次幂,但是会导致下面的循环不会执行,然后返回trueif (n < 1) return false;while (n > 1) {int t = n / 2;if (t != n / 2.0) return false;n /= 2; }return true;}
};// 方法2:位运算
// 原理:2的幂的二进制的共同特征为:仅最高位是 1,其余全为 0,相当于1后面跟的全部是0
// 判断原理:用 n & (n - 1)消去最低位的1,如果能抵消得出的是0,那么就是2的幂
// 如果是2的幂:8 & 7 → 1000 & 0111 = 0000
// 如果不是2的幂:6 & 5 → 0110 & 0101 = 0100// 代码过程:
// 1 特判:如果n <= 0,直接返回false,因为2的幂都是正数
// 2 关键操作:使用n & (n - 1)来消除最低位的1
// 如果n是2的幂,那么n & (n - 1)的结果会是0, 例如:8 & 7 → 1000 & 0111 = 0000
// 3 返回结果:如果结果为0,则是2的幂,否则不是class Solution2 {
public:bool isPowerOfTwo(int n) {// 特判:如果输入的是<1的数字,但并不是2的次幂,但是会导致下面的循环不会执行,然后返回true// 特判和普通判断写一起了,代码简洁了很多return n > 0 && (n & (n - 1)) == 0;}
};
int main(void) {ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);// int n = 1;int n = 16;// int n = 3;Solution sol;cout << sol.isPowerOfTwo(n) << '\n'; Solution2 sol2;cout << sol2.isPowerOfTwo(n);return 0;
}