题目如下:
Given an integer, write a function to determine if it is a power of two.
多么朴实无华的题干,输入一个数,判断是否能写成2的X次幂这种形式。比如输入8就返回true,因为2的三次幂是8;输入16就返回false,因为2的任何次幂都不是16。
最朴实,最容易想到的方法如下:
<span style="font-size:14px;">public boolean isPowerOfTwo(int n) {
if(n <= 0){
return false;
}
while (n > 1){
if(n % 2 == 0){
n = n / 2;
} else {
return false;
}
}
return true;
}</span>
算法很直白,没什么可解释的。这里要说明的是另一种很神奇的方法,它是根据整数所对应的二进制数,特别是2的X次幂整数对应的二进制数的特殊性来判断的。
这种很神奇的方法如下所示:
<span style="font-size:14px;">public boolean isPowerOfTwo(int n) {
if(n<=0) return false;
if((n & (n-1)) == 0){
return true;
}else{
return false;
}
}</span>
在讨论区,原文是这样说明的:
Power of 2 means only one bit of n is '1', so use the trick n&(n-1)==0 to judge whether that is the case
翻译过的意思就是:
所有2的X次幂都有一个共同性质,就是它们二进制形式中只有一个位的值为“1”,所以将该数进行“减一”操作后,得到的二进制数应该是原来是“1”的那一位和其左侧的位的值都是“0”,右侧的位的值都为“1”,所以将这两个数进行“与”操作后,得到的结果是“0”。我们可以通过这种方式判断一个数是不是可以写成2的X次幂这种形式。
举一个例子,8的二进制可以写成1000,8-1=7的二进制是0111,它们进行“与”操作后结果是0,所以8可以写成2的X次幂这种形式。而6的二进制是0110,6-1=5的二进制是0101,它们进行“与”操作后结果是0100=4不为0,所以6不能写成2的X次幂这种形式。
这种特殊解法还是需要长期的知识积累的,像本人这种too simple的以后还是要多学习一个,这样才能在今后的学习中跑得比别人快。