大家好我是好好學習天天編程的天天
一個整天在互聯網上種菜和砍柴的程序員~
大量面試題中會考算法,當然其中也有一些小算法,是比較考察候選人思維的,所以出現的頻次比較高。就比如下面這個:
題目描述:
判斷一個數是否爲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;
}
好了,這個題就分享在這裏,有什麼問題,留言區見。
如果文章對你有用,幫忙點個贊,鼓勵一下作者。
更多學習資料請點擊:學習資料領取