【面试题】判断一个数是否为2的N次方---终极解法来啦

大家好我是好好学习天天编程的天天
一个整天在互联网上种菜和砍柴的程序员~

大量面试题中会考算法,当然其中也有一些小算法,是比较考察候选人思维的,所以出现的频次比较高。就比如下面这个:
题目描述:

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

方法1

其实是一个题,知识不同的描述方式啦
那怎么求解呢?
很多人的思路就是直接做除2的操作么,但是这种思路,其实很难验证,除到什么时候算是结束呢?所以不合适。

那相反的思路,不断的算出2的幂次方的数来穷举,直到算出的等于或者超出这个数本身。如果是等于了,那就就是2的幂次方,如果是超过了,那就不是。

算法实现如下:


#include <stdio.h>

//使用judge函数判断num是否为2的幂次方
int judge(int num)
{
    int ret = 1;
    while (ret<=num)
    {
        //如果小于,则说明还没穷举完
        if (ret < num)
        {
            //每次产生一个2的幂次方数
            ret *= 2;
        }
        else
        {
            //是
            return 1;
        }
    }
    //不是
    return 0;
}
int main()
{
    int num = 0;
    scanf("%d", &num);
    int ret = judge(num);
    if (ret == 1)
    {
        printf("%d 是2的幂次方\n", num);
    }
    else
    {
        printf("%d 不是2的幂次方\n", num);
    }

    return 0;
}

方法2

但是方法1这种算法的时间复杂度比较高,面试官可能不满意
面试官还会追问你,还有其他方法吗?
下面我给出终极解决方案:

分析:

其实一个数n,如果是2的幂次方数,则n的二进制的补码中一定只有一个1,那n&(n-1)就会让n的2进制补码中的1小时,那n&(n-1) == 0。

根据这个思路,如果n&(n-1)的结构是0,则n是2的幂次方,如果不是0,则n不是2的幂次方。

如果你现在还有疑惑,你随便举个例子,带进去算一下,就明白了

比如:
例1:n是2的幂次方
n   = 8
n-1 = 7
0000 1000
0000 0111  &
-------------
0000 0000

例2:n不是2的幂次方
n   = 7
n-1 = 6

0000 0111
0000 0110  &
------------
0000 0110

如果明白了,请看代码:

#include <stdio.h>

//使用judge函数判断num是否为2的幂次方
int judge(int n)
{
    if ((n&(n - 1)) == 0)
        return 1;
    else
        return 0;
}

int main()
{
    int num = 0;
    scanf("%d", &num);
    int ret = judge(num);
    if (ret == 1)
    {
        printf("%d 是2的幂次方\n", num);
    }
    else
    {
        printf("%d 不是2的幂次方\n", num);
    }

    return 0;
}

好了,这个题就分享在这里,有什么问题,留言区见。
如果文章对你有用,帮忙点个赞,鼓励一下作者。

更多学习资料请点击:学习资料领取
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章