【面试题】判断一个数是否为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;
}

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

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

posted @ 2020-05-27 19:00  好好学习天天编程  阅读(590)  评论(0编辑  收藏  举报