Tweaks
Character c;
for (int i = 0; i < characters.length; i++) {
c = characters[i];
You can write this more simply as
for (Character c : characters) {
Then i
is Java's problem.
Plus, this is clearer. It says directly what is being done. For each character in the string, do these things.
j += 1;
You could write this as
j++;
which is more idiomatic.
}
if (c.equals('1')) {
You could replace this with either
} else if (c == '1') {
or
} else {
After all, what else would it be? It's a binary string. And obviously you don't have to check that it's not '0'
. You just did that.
You don't need to use equals
with a character, as it reduces to a primitive type (char
). You can do so here, but you don't have to do so.
I'd move the println
outside the method. Then you can choose to output or not.
Performance
Very little of that will make any performance difference. What could though would be to stop mucking with strings. It's possible to work directly with the integer.
public static int solution(int N) {
int binaryGap = 0;
// Special case
if (N == 0) {
return 0;
}
// remove trailing zeroes if not counted; credit to Peter Taylor
while (N % 2 == 0) {
N /= 2;
}
for (int j = 0; N > 0; N /= 2) {
if (N % 2 == 0) {
j++;
} else {
if (j > binaryGap) {
binaryGap = j;
}
j = 0;
}
}
return binaryGap;
}
This is essentially what the Integer.toBinaryString
does to build the string. Doing it like this means that we don't have to do it twice.
You could also use bit operations instead of division and modulus. Ideally the compiler should do that for you if it would be faster. But you could benchmark instead.
There's an argument that you should leave the declaration of j
outside the for
loop. Since you don't iterate over j
. But you also don't use j
outside the loop, so the scope is right this way.