目录
题目:
给定一个正整数,检查它是否有交替位:也就是说,两个相邻位是否总是有不同的值。
思路:
一、检查一个位是0还是1的同时,与保留状态比较。
二、构造一个跳动信号,每次循环跳动,并且与输入数字比较
更多思路参考:0/1交替
要点:
1、使用思路一时,我们知道逐一检查一个数字的各个位有两种方法,一是令flag = 1,将flag左移,与num;另一种是令num右移,再跟1与。后者适用于num>0,循环结束的时候,num == 0;一般来说前者循环结束的信号是flag == 0,但是本题不允许对高位的0序列检查(很显然连续的0会导致程序输出为false,但是实际答案是true),怎么办?例子:0000101010,我们只需要检查101010满足要求即可。
我们添加判断条件:flag<=Integer.highestOneBit(n)作为循环条件,这样flag最多左移到100000.
2、搞定上一个问题就ok?对于用例num = 1010101 01010101 01010101 01010101(这是二进制)呢?
使用1中的方法后,flag最大为1000000 00000000 00000000 00000000,此时flag再左移就变成了0,并且会是连续的0,同样不满足要求,会导致程序输出成false;所以循环结束条件需要加上 flag!=0.
3、思路二中的跳动信号的构造,见下面的代码(方法helper2(int n))
解法:
class Solution {
public boolean hasAlternatingBits(int n) {
return helper2(n);
}
/*
解法一:
对每一位比较(利用与1实现),记录上一位的数值
用例:1010101 01010101 01010101 01010101,如果没有flag!=0的限制条件,flag的下一跳即将变成0,并且后来flag全部是0
*/
private boolean helper(int n){
int rec = -1;
int flag = 1;
while(flag<=Integer.highestOneBit(n)&&flag!=0){
if((n&flag) == 0){
if(rec == 0) return false;
rec = 0;
}
else{
if(rec == 1) return false;
rec = 1;
}
flag = flag<<1;
}
return true;
}
private boolean helper1(int n){
int rec = -1;
while(n>0){
if((n&1) == 0){
if(rec == 0) return false;
rec = 0;
}
else{
if(rec == 1) return false;
rec = 1;
}
n = n>>1;
}
return true;
}
/*
解法二:
每次循环比较一个位,每个循环右移n一位,信号量d跳动一次
d^=1可以构造一个跟随循环跳动的信号量
*/
private boolean helper2(int n){
int d = n&1;
while(d == (n&1)){
d^=1;
n = n>>1;
}
return n==0;
}
}