判断一个数是否4的次幂_二分法解法

力扣看题,发现一道简单题,判断一个数是否是4的次幂

写了这个之后,发现他们都是直接除法,或者用上了log.
不过这题的tag既然是位运算,大概都没有符合题意把XD

解题思路

  • 首先不会是负数,排除掉 , 然后4的指数和2的指数,区别就是4的指数是特殊的2的指数 , 2的指数只有一个bit,然后既然只有一个bit,只通过前置bit数量可以知道数值的大小,
  • 然后如果前置bit为0的个数是奇数个,就是4的指数 , 前置零的方法在integer里面有,这里改造一下可以用到这道题里面.
  • 原方法是舍弃后面,只取最高位 , 你把他的移位-1(就是纯1数) , &一下看他有没有为1的bit位, 有的话加上之前的bit位说明bit位个数大于一个了,直接返回false就行(再解释一下就是例如n >= half1那个判断,你知道他前16位是一定有个1的 , 此时你用 & 一下 (1<<16) - 1 , 说明后面16位也有一个1 , 那么bit位1的个数至少两个 , 是不符合4的次幂的 , 直接pass )

int32哥bit位,而且2和4的次幂只有一个bit , 天然的适合用二分法来解

代码


    private boolean isPowerOfFour_try02(int n) {
        if (n <= 0) {
            // 如果是负数 , 那么首位是1 , 没有前置0 , 如果是0就是32位,  所以特殊处理 .
            // 这里场景是4的指数 , 小于等于0可以pass了,不会是负数
            return false;
        }
        // 这里采用的是二分法的思想 , 就和那个10次以内才出1000以内的任何数字一样 , 每次把key缩小一倍去判断 . 找到第一个非0位置 .
        int leadTemp = 31;
        int nCopy = n;
        if (n >= 0x10000) {
            leadTemp -= 16;
            n >>>= 16;
        }
        if (n >= 0x100) {
            leadTemp -= 8;
            n >>>= 8;
        }
        if (n >= 0x10) {
            leadTemp -= 4;
            n >>>= 4;
        }
        if (n >= 4) {
            leadTemp -= 2;
            n >>>= 2;
        }
        int leadZero = leadTemp - (n >>> 1);
        return leadZero % 2 == 1 && (nCopy & ((1 << (31 - leadZero)) - 1)) == 0;
    }


解法2

补码中 , 负数的补码有个规律, 就是先把一个正数中所有位取反 , 然后再+1 .
实际上这样就可以用 i & -i来获取某个数只保留最右侧一个bit为1的数 , 如果这个数等于本身说明本身只有一个bit .
例如 100 , 负数的补码就是 若干个1然后接着100 .
所以2的指数可以用 n > 0 && n == (n & -n) 判断 , 再加上首位0的个数是奇数 . && Integer.numberOfLeadingZeros(n) % 2 == 1.
方法就是


{
    return n > 0 && Integer.numberOfLeadingZeros(n) % 2 == 1 && n == (n & -n);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值