判断一个数字是否是2的N次方

简介: 判断一个数字是否是2的N次方

今天看到小伙在看一个判断一个数是否为2的N次方的博客,我有点印象,就过去装逼了结果一下子还真没想出来,装逼失败!

这道题目其实是 leetcode 上面的第231道题目,题目内容如下:

给定一个整数,编写一个函数来判断它是否是 2 的幂次方
• 1

 我一开始是想到如果是10进制内10的多少次方的时候应该是什么样子:

10^n 数值 n
10^0 1 0
10^1 10 1
10^2 100 2
10^3 1000 3

我们很自然的看出来,如果我们平时的10进制,其实就是一位数上是1,其他都是0。这个想到我们计算2^n的时候,应该是1,2,4,8,16依次下去,由此想到这种情况下在二进制的情况:

2^n 数值 10进制
2^0 1 1
2^1 10 2
2^2 100 4
2^3 1000 8

我们其实很容易发现,2的多少次方的情况就是二进制位数上一个数是1其他都是0,我们的思路其实就是想办法把二进制数中的1消掉,剩下的是0就行,当然前提条件是这个数>大于0,我们可以使用二进制的中的清零最低位的1操作x&(x-1),这个表示的是我们把最低位的1去掉,看看剩下的值,运算过程如下:

2^n n n-1 n&n-1
2^0 1 0 0
2^1 10 01 00
2^2 100 011 000
2^3 1000 0111 0000

其他情况也可以看看

十进制 n n-1 n&n-1
3 11 10 10
5 101 100 100
6 110 101 100
7 111 110 110

可以看到n&(n-1)的效果就是会把n的二进制位最低的那位1抹掉,在2^n次方的情况抹掉一个0剩下的就全是0了,其他情况的话不会是0,所以相应的只要位运算的操作就可以出来结果,代码贴上,附上测试数据:

public class Leecode_231_35 {

    public static void main(String[] args) {
        Leecode_231_35 lc = new Leecode_231_35();
        System.out.println(lc.isPowerOfTwo(0));
        System.out.println(lc.isPowerOfTwo(1));
        System.out.println(lc.isPowerOfTwo(2));
        System.out.println(lc.isPowerOfTwo(3));
        System.out.println(lc.isPowerOfTwo(4));
        System.out.println(lc.isPowerOfTwo(5));
        System.out.println(lc.isPowerOfTwo(6));
        System.out.println(lc.isPowerOfTwo(7));
        System.out.println(lc.isPowerOfTwo(8));
        System.out.println(lc.isPowerOfTwo(9));
        System.out.println(lc.isPowerOfTwo(-2147483648));
    }

    public boolean isPowerOfTwo(int n) {
        return n > 0 && (n &= n - 1) == 0;
    }
}

当然,这种高效一次运算的操作,自然时间复杂度就是最最让人喜欢的O(1)了

目录
相关文章
|
7月前
|
Python
如果一个n位正整数等于其各位数字的n次方之和
如果一个n位正整数等于其各位数字的n次方之和
|
算法 测试技术 C#
C++数位算法:数字1的个数
C++数位算法:数字1的个数
|
1月前
判断该数字是几位数
【10月更文挑战第22天】判断该数字是几位数。
19 3
|
2月前
判断该数字是正数还是负数或是零
【10月更文挑战第15天】判断该数字是正数还是负数或是零。
53 2
|
2月前
判断一个数字是否为质数
判断一个数字是否为质数。
124 9
|
7月前
28.求任意一个整数的十位上的数字
28.求任意一个整数的十位上的数字
85 3
|
7月前
|
Java
如何判断科学计数法3.14E+308 在区间3.14E+38和 3.14E+1308内
对于非常大的科学计数法表示的数值,直接将其转换为 `double` 类型可能会导致溢出。Java 中的 `double` 类型表示的最大值约为 `1.7976931348623157E+308`,因此 `3.14E+308` 已经超出了其表示范围。如果需要处理超出 `double` 类型表示范围的数值,可以使用 `BigDecimal` 类来处理。 以下是一个示例,展示如何使用 `BigDecimal` 类来比较科学计数法表示的数值是否在指定区间内: ```java import java.math.BigDecimal; public class ScientificNotationC
判断数字位数
判断数字位数
81 0
|
C语言
已知一个整数,如何判断这个整数是无符号的?
已知一个整数,如何判断这个整数是无符号的?
100 0
一个数字的二进制数字里的一的个数(负数用补码)
这是一种解决问题的函数,缺点,会有死循环,((int)pow(-2, i))这个值的结果是整形永远达不到那个数字2147483648,我们必须自己规定那个数字
56 0