Bootstrap

位运算 -leetcode -231. 2 的幂

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<=2311

暴力

写法1:乘法

思路:

  • 依次枚举,直至 c n t > = n cnt >= n cnt>=n

注意:

  • 使用 long 防止 c n t cnt cntint溢出
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}) (2n1) 对应的二进制都是 ( 111..1 ) 2 (111..1)_2 (111..1)2,所以要判断 n 是否为 2 n 2^n 2n,则可以通过判断 (n - 1) 是否等于 2 n − 1 2^{n - 1} 2n1 来进行
    • 即, 只要 (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 ⭐️ 🔥

思路:🤔

  1. 2 2 2 的次幂(指数函数)一定大于0,所以非正数一定不可能为2的次幂…
  2. 对于正整数而言:
    1. 2 n 2^n 2n 的次幂转换为二进制后,一定是形式为:第一位为1,后n位均为1,即 1000..000 1000..000 1000..000形式;
    2. 2 n − 1 2^n-1 2n1的次幂转换为二进制后,一定是形式为:所有的n-1位均为1,即 111...1 111...1 111...1 形式;
    3. 所以, 2 n 2^{n} 2n& 2 n − 1 = = 0 2^{n-1}==0 2n1==0 时,表示 n u m s nums nums 为2的次幂;否则,则不是

例如 🌰

  • n u m s = 8 nums=8 nums=8时,其二进制为 1000 1000 1000 n u m s − 1 = 7 nums-1=7 nums1=7,其二进制为 111 111 111,即 2 n 2^{n} 2n& 2 n − 1 = = 0 2^{n-1}==0 2n1==0,所以8是2的次幂;
  • n u m s = 7 nums=7 nums=7,其二进制为 111 111 111 n u m s − 1 = 6 nums-1=6 nums1=6,其二进制为 110 110 110,即 2 n 2^{n} 2n& 2 n − 1 = = 1 2^{n-1}==1 2n1==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)
;