一、题目描述
Given a positive integer N,
find and return the longest distance between
two consecutive 1's in the binary representation of N.
If there aren't two consecutive 1's, return 0.
例如,数字9具有二进制表示1001,包含长度为2的二进制间隙。
数字529具有二进制表示1000010001,并且包含两个二进制间隙:长度4和长度3的一个。
二、题解
(1) 计数法
每次遇到 位1
,则重新开始记录并比较0的数量zeroCnt
,取它的最大值。
/**
* @param N
* @return
*/
public int binaryGap1(int N) {
int ans = 0;
int zeroCnt = 0;
while(N >= 1) {
// 只有遇到1以后,的0才会被计数,不然如果N==8(1000),会返回3
if((N & 1) == 0 && zeroCnt > 0) {
zeroCnt++;
}else if((N&1) == 1){
ans = ans > zeroCnt ? ans : zeroCnt;
zeroCnt=1;
}
N >>= 1;
}
return ans;
}
(2) 数组记录位 1 的索引法
用record
数组记录每一个位1
的索引,遇到1则指向1的指针自增1。而全局指针每次加1,在最后两两比较record
数组的每一个元素的差值,得出最大值。
/**
* @param N
* @return
*/
public int binaryGap2(int N) {
int ans = 0;
int i = 0; // 指向位1的指针。
int[] record = new int[32];
for (int j = 0; j < 32; j++) {
if ((N & 1) != 0)
record[i++] = j; // 记录位1的下标。
N >>= 1;
}
for (int k = 0; k < record.length-1; k++) {
ans = Math.max(ans, record[k+1]-record[k]);
}
return ans;
}
(3) 不使用额外数组空间
不难想到,其实无需开辟一个数组来存储位 1 的下标,只需每次更新最后的位 1 二进制位下标,每次更新后,并且与之间的得到的临时最大间隔gap
进行比较即可。
/**
* @param N
* @return
*/
public int binaryGap3(int N) {
int gap = 0, last = -1;
for (int i = 0; i < 32; i++) {
if((N&1) == 1) {
if(last >= 0)
gap = Math.max(i-last, gap);
last = i;
}
N >>= 1;
}
return gap;
}