blog
blog copied to clipboard
编写一个函数来确定它是否是2的幂
给定一个整数,编写一个函数来确定它是否是2的幂。(范围:1 - 2^31-1)
测试用例:
输入 : 16, 输出 : true 因为 2^4 = 16
输入 : 18, 输出 : false.
方法1
最明显的暴力方法就是除以2,然后检查它是否达到1。
var powerOftwo = function(n){
if(n<=0) return false;
while(n%2 == 0) n = n/2;
return n == 1;
}
方法2
由于给出的范围在0-2^31-1之间,我们可以使用这个范围来计算各种可能的输出,将它们保存到一个集合中并进行检查:
let set = new Set();
for(let i=0;i<31;i++){
set.add(Math.pow(2,i));
}
console.log(set);
var powerOfTwo = function(n){
if(set.has(n)) return true;
return false;
}
方法3
每一家公司提出一个看起来易于理解和实现的问题时,这个问题一定与位操作有关。
对于计算机来说,一切都归结为0和1的组合,包括数字。那么让我们来看看n=0到31时,表示2^n的数字是如何以位的形式表示的。
根据上图我们找到规律是:2的幂的数字只有1位被设置为1,其余的为0。
位操作符用于在最基本的层次上,即按内存中表示数值的位来操作数值。
按位非操作符由一个波浪线(~)表示,,执行按位非的结果就是返回数值的反码。
var num1 = 25; // 二进制00000000000000000000000000011001
var num2 = ~num1; // 二进制11111111111111111111111111100110
alert(num2); // -26
按位与操作符由一个和号字符( & )表示,它有两个操作符数。从本质上讲,按位与操作就是将两个数值的每一位对齐,然后根据下表中的规则,对相同位置上的两个数执行按位与操作:
第一个数值的位 | 第二个数值的位 | 结果 |
---|---|---|
1 | 1 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
0 | 0 | 0 |
按位或操作符由一个竖线符号(|)表示,同样也有两个操作数。按位或操作遵循下面这个真值表。
第一个数值的位 | 第二个数值的位 | 结果 |
---|---|---|
1 | 1 | 1 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
按位异或操作符由一个插入符号(^)表示,也有两个操作数。以下是按位异或的真值表。
第一个数值的位 | 第二个数值的位 | 结果 |
---|---|---|
1 | 1 | 0 |
1 | 0 | 1 |
0 | 1 | 1 |
0 | 0 | 0 |
因此,我们的代码归结为:
var powerOfTwo = function(n){
n = n&(n-1);
return n == 0;
}