Loading

【LeetCode】231. Power of Two

题目:

给定一个整数,判断它是不是2的次幂。

Example 1:

Input: 1
Output: true 
Explanation: 2^0=1

Example 2:

Input: 16
Output: true
Explanation: 2^4=16

Example 3:

Input: 218
Output: false

思路:

2^{0}=12^{1}=22^{3}=82^{4}=162^{5}=32......

这些数字都可以不断地整除2,直到最后结果为1。

比如:64 / 2 = 32, 32 / 2 = 16, 16 / 2 = 8, 8 / 2 = 4, 4 / 2 = 2, 2 / 2 = 1。

如果一个数不是2的次幂,那么中间一定会断掉。

比如:12 / 2 = 6, 6 / 2 = 3, 3就不能整除2了。

那么比较容易想到的方法就是把这个数不断地除以2,直到余数不为0。

判断余数,如果是1,则返回true;否则返回false。

#include <stdio.h>
#include <stdbool.h>

bool isPowerOfTwo(int n) {
    if (n <= 0)    //2的次幂不会是0或负数
        return false;
    while (n % 2 == 0) {
        n = n / 2;
    }
    if (n == 1) return true;
    else    return false;
}

int main()
{
    printf("%d\t", isPowerOfTwo(1));
    printf("%d\t", isPowerOfTwo(32));
    printf("%d\t", isPowerOfTwo(1024));
    printf("%d\t", isPowerOfTwo(1025));
    return 0;
}

结果:

几乎所有的提交结果都是4ms左右。注意别忘了0的情况。

虽然这个结果还可以,但还可以改进。因为这个方法就是反复地做除法,虽然对于人来讲很容易想到,但是对计算机而言就不同了,计算机很不擅长除法,必然耗时会多一些。


改进思路:

(1)_{10} = (1)_{2}

(2)_{10} = (10)_{2}

(4)_{10} = (100)_{2}

(8)_{10} = (1000)_{2}

(16)_{10} = (10000)_{2}

(32)_{10} = (100000)_{2}

......

可以看到,2的次幂转换为二进制,都是1后面有若干个0。

以8为例,8转换为二进制是1000,1000 - 1 = 0111,(1000) & (0111) = 0000。

所以可以将给定整数n与n-1进行与运算,如果结果为0,那么n就是2的次幂。

仅需计算一步即可得出结果,免去了循环。

#include <stdio.h>
#include <stdbool.h>

bool isPowerOfTwo(int n) {
    if (n <= 0)    //2的次幂不会是0或负数
        return false;
    else {
        if ((n & (n-1)) == 0)
            return true;
        else
            return false;
    }
}

int main()
{
    printf("%d\t", isPowerOfTwo(1));
    printf("%d\t", isPowerOfTwo(32));
    printf("%d\t", isPowerOfTwo(1024));
    printf("%d\t", isPowerOfTwo(1025));
    return 0;
}

结果:


参考:一起玩算法03

推荐一位干货up主:正月点灯笼

posted @ 2019-01-19 23:06  江南笑书生  阅读(92)  评论(0编辑  收藏  举报