交替位的二进制数

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,否则一点点向左比较。


这个算法,更淳朴,而且运算速度更快。

就是这样,有时候以为自己抄了个近道,其实不如老老实实的做运算,来的更快。

做题也好,做人也罢,还是要回归最初本心才好。

posted on 2018-01-23 22:40  sannere  阅读(266)  评论(0)    收藏  举报

导航