java数据结构与算法刷题-----LeetCode231. 2 的幂

java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.youkuaiyun.com/grd_java/article/details/123063846

文章目录

在这里插入图片描述

位运算

解题思路:时间复杂度O( 1 1 1),空间复杂度O( 1 1 1)
  1. 我们观察正整数中2的幂的二进制表现形式的规律:
  1. 2 0 = 1 = 0001 2^0=1=0001 20=1=0001
  2. 2 1 = 2 = 0010 2^1=2=0010 21=2=0010
  3. 2 2 = 4 = 0100 2^2=4=0100 22=4=0100
  4. 2 3 = 8 = 1000 2^3=8=1000 23=8=1000
  1. 也就是说正数中的2的幂,满足一个很重要的条件,那就是整个二进制串只有一个1
  2. 而题目明确指出,给出的n是整数。也就是说,我们不需要考虑负次幂的情况,例如 2 − 1 = 0.5 , 2 − 2 = 0.25 等 2^{-1}=0.5,2^{-2}=0.25等 21=0.5,22=0.25
  3. 则我们现在的算法就可以简化为,对n的二进制代码最后一个1操作判断即可
  1. 去除2进制串中最后一个1后,剩余2进制串结果为0.就说明是2的幂,例如 2 3 = 8 = 1000 2^3=8=1000 23=8=1000,取出最后一个1变为 0000 = 0 0000 = 0 0000=0

这个操作也比较经典,Brian Kernighan算法可以方便的实现去除二进制串种末位1的效果。也就是s = n&(n-1),s为n二进制去除末位1的结果串

  1. 只取末位1,如果刚好=n,说明是2的幂。例如 2 3 = 8 = 1000 2^3=8=1000 23=8=1000,只取末位1为 1000 = 8 1000 = 8 1000=8.发现相等,锁门n是2的幂。再比如 n = 十 = 二进制 1010 n = 十 = 二进制1010 n==二进制1010,只取末位1为 0010 = 2 0010 = 2 0010=2,发现结果2和n不相等,说明n的二进制串不是只有一个1.因此n = 10不是2的幂

这个操作也是经典,只需要通过n&(-n)就可以只取出末位的1

  1. 以上用到的位运算操作,不懂的可以参考下面的文章中与运算的说明
位运算https://blog.youkuaiyun.com/grd_java/article/details/136119268

另外,很重要的一点是,2的幂不可能为负数。因为一个正数的n次幂依然是正数。

代码
  1. n的2进制串去除末位1后,剩下的二进制是否为0
    在这里插入图片描述
class Solution {
    public boolean isPowerOfTwo(int n) {
        return n > 0 && (n & (n-1)) == 0;//n必须是正数,因为2的幂不可能为负数
    }
}
  1. 只取末位1,结果和n一样,说明是2的幂
    在这里插入图片描述
class Solution {
    public boolean isPowerOfTwo(int n) {
        return n > 0 && (n & -n) == n;//n必须是正数,因为2的幂不可能为负数
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ydenergy_殷志鹏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值