源地址
https://app.codility.com/programmers/lessons/1-iterations/binary_gap/
BinaryGap(二进制缺口)
一个正整数N的二进制缺口,指的是N的二进制中头尾两端都被1包围的最长串的连续的0。
比如
- 数字9的二进制形式为「1001 」,包含一个长度为2的BinaryGap。
- 数字529的二进制形式为「1000010001」,包含两个BinaryGap:一个长度为4,一个长度为3。
- 数字20的二进制形式为「10100 」,包含一个长度为1的BinaryGap。
- 数字15的二进制形式为「1111」,没有BinaryGap。
- 数字32的二进制形式为「100000」,没有BinaryGap。
写一个函数
class Solution {
public int solution(int N);
}
给定一个正整数N,返回它的最长BinaryGap。如果不包含任何BinaryGap,那么返回0。
比如,N=1041,函数返回5,因为N的二进制形式是「10000010001」,所以他的最长BinaryGap的长度是5。N=32,函数返回0,因为N的二进制形式是「100000」而他没有BinaryGap。
前提如下:
- N 是一个范围为[1…2,147,483,647]的整数。
第一步
最容易想到的就是双层循环,遍历两次。取最大值。
时间复杂度为O(M2)。 (M为给定自然数N的二进制形式的位数)
public int solution(int N) {
char[] c = Integer.toBinaryString(N).toCharArray();
int len = c.length;
int result = 0;
// the start position of BinaryGap
for (int start = 0; start < len - 1; start++) {
if (c[start] == '1') {
continue;
}
// the end position of BinaryGap
int end = start + 1;
while (end < len) {
if (c[end] == '1') {
break;
}
end++;
}
if (end < len && c[end] != '0') {
result = Math.max(result, end - start);
}
}
return result;
}
第二步
更快的做法是,只循环一次,找到每两个1之间的gap。
时间复杂度为O(M) (M为给自然数的二进制形式的位数)
public int solution(int N) {
char[] c = Integer.toBinaryString(N).toCharArray();
int len = c.length;
int result = 0;
int pre = 0;
for (int i = 0; i < len; i++) {
if (c[i] == '1') {
result = Math.max(i - pre - 1, result);
pre = i;
}
}
return result;
}