源地址
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;
}