LeetCode第 342 题:4的幂(C++)

342. 4的幂 - 力扣(LeetCode)

常规方法

class Solution {
public:
    bool isPowerOfFour(int num) {
        if(num < 1)   return false;
        while(num > 1){
            if(num % 4) return false;
            num /= 4;
        }
        return num == 1;
    }
};

位运算

可以参照LeetCode第 231 题:2的幂(C++)_zj-CSDN博客

4的0 ~ n次方,等于 2的0,2,4,6…2n(全为偶数) 次方。4的幂次方的二进制里,同样只有一位是置1的, 而且置1的位应该处于二进制中从右往左的数的第1//3/5/7/9…上面。比如16:

  1:00000000  00000000  00000000  0000 0001
  4:00000000  00000000  00000000  0000 0100
16:00000000  00000000  00000000  0001 0000

所以两个条件:二进制数只有一位置1, 置 1 的位置对应数字是奇数。

但是第二个条件怎么用代码表示呢?先强调第二个条件是建立在第一个条件满足的情况下讨论的

比如16,二进制后8位是:0001 0000,置位的1在右往左的第5位(奇数),怎么去判断在第几位呢?

先用 num | (num-1),就变为 0001 1111,问题就变成了求二进制数里面1的个数是不是奇数。

先贴一个使用bitset的方法,几种判断条件可以合并在一起的:

v & -v 的作用就是取出右起连续的 0 以及首次出现的 1

class Solution {
public:
    bool isPowerOfFour(int num) {
        if(num <= 0)  return false;
        if((num & -num) != num)   return false;//检测是否只有一位置1
        return bitset<32>(num | (num-1)).count() % 2;
    }
};

或者换个思路,第二个条件也可以理解为二进制数末尾有多少个0,如果是偶数个,那该数就是4的幂,否则就不是。那有怎样检测一个二进制数末尾有多少个0呢?看到一个很厉害的方法(并不能看懂):神秘常量0x077CB531,德布莱英序列的恩赐 - 游戏程序员刘宇 - 博客园

class Solution {
public:       
    int MultiplyDeBruijnBitPosition[32] = {
     0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 
    31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};

    bool isPowerOfFour(int num) {
        if(num <= 0)  return false;
        if((num & -num) != num)   return false;//检测是否只有一位置1
        int r = MultiplyDeBruijnBitPosition[(((num & -num) * 0x077CB531U)) >> 27];
        return r % 2 == 0;
    }
};

好吧,还有更简单的方法:

4的幂 - 4的幂 - 力扣(LeetCode)

还是接着上面的第二个条件,需要判断1的位置,那就与:

10101010 10101010 10101010 10101010

进行与操作就可以,即为16进制的aaaaaaaa:

class Solution {
public:       
    bool isPowerOfFour(int num) {
        return (num > 0) && ((num & (num - 1)) == 0) && ((num & 0xaaaaaaaa) == 0);
    }
};

或者:若 x 为 2 的幂且 x%3 == 1,则 x 为 4 的幂。

class Solution {
public:       
    bool isPowerOfFour(int num) {
        return (num > 0) && ((num & (num - 1)) == 0) && (num%3 == 1);
    }
};

log换算

4的幂对2取log,除以2,判断奇偶就行

class Solution {
public:       
    bool isPowerOfFour(int num) {
        //floor(a)返回不大于a的最大整数
        return num > 0 && log2(num)/2 == floor(log2(num)/2);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值