交替位的二进制数
693. Binary Number with Alternating Bits
Given a positive integer, check whether it has alternating bits: namely, if two adjacent bits will always have different values.
判断一个数的二进制表示,每一位是否为交替的,eg:1 0 1 0 1
看懂题的第一反应,就是把一个整形的数,先转化为二进制的字符,再存放到一个数组里,再判断相邻位是否不同。
等操作起来,太复杂了~~
后来想到了可以直接用整数做的运算:异或。
一个数n,把n错一位得到m,如果n是交替二进制的数,那么n和m对应的每一位都是不同的,即n^m=111111.....
那么n|m也是一样得到111111.....,即n^m === n|m。
但是!
如果给的数是这种1 0 0 1
出现了连续个0,那么n^m虽然不为连续个1,但是错位后的m,和n当中会有一位都为0.
即n: 1 0 0 1
m: 0 0 1 0
第三位,m和n都为0,就是说,虽然他们n^m判断为1 0 1 1,不是连续个1,但是n|m也为1 0 1 1,n^m 依旧==n|m.
后来想到了(高人指点后),把n右移一位,而不左移,得到m,再做n^m,得到连续的1.
把连续的1这个数+1,得到1000....(全部进一位,得到多一位数的100000...),那么连续个1111...,与10000...连续个0,做&运算,肯定为0.
即 n: 1 0 1 0 1 0
m: 0 1 0 1 0 1
m^n 01 1 1 1 1 1
m^n+1: 1000000
m^n & m^n + 1: 0`
/**
* @param {number} n
* @return {boolean}
*/
var hasAlternatingBits = function(n) {
var m = n >> 1;
var MxorN = m ^ n;
if((MxorN & (MxorN + 1)) === 0)
return true;
else
return false;
};
不过还是看到了更快更本质的一个算法。
var hasAlternatingBits = function(n){
let ad = 2;
while(n > 0) {
if (ad === n%2)
return false;
ad = n%2;
n = Math.floor(n/2);
}
return true; };
//n/2即左移一位的数,n%2为当前为的值。如果左一位%2 == 当前为%2,那么,这两位相同,直接返回false,否则一点点向左比较。
这个算法,更淳朴,而且运算速度更快。
就是这样,有时候以为自己抄了个近道,其实不如老老实实的做运算,来的更快。
做题也好,做人也罢,还是要回归最初本心才好。
浙公网安备 33010602011771号