4

I am trying to solve binary gap problem using recursion. It can be easily solved without recursion. But I want to solve this with recursion.The below program takes an integer as input and finds the binary gap.

Example:

input= 9, Binary form = 1001, Answer = 2

input=37, Binary form = 100101, Answer = 2

It finds the maximum number of zeros that occur between two 1's in the binary representation.

I want to solve this in O(logn). Right now, the below program simply counts the total number of zeros and gives output 3 instead of 2. How do I correct this to get the right output?

class BinaryGap {

    public int solution(int N){

     return solution(N, false, 0);   
    }
    public int solution(int N, boolean prevFlag, int memo) {

        if(N<2)
            return 0;

        int remainder = N%2 ;


        if(prevFlag){
            if(remainder == 0){
                memo = 1 + solution(N/2, prevFlag, memo);
            } else {
                int newGap = solution(N/2, prevFlag, memo);

                if(newGap > memo)
                    memo = newGap;
            }
        } else {

            prevFlag = (remainder == 1);
            return solution(N/2, prevFlag, 0);
        }

        return memo;

    }

    public static void main(String args[]){
        BinaryGap obj = new BinaryGap();

        System.out.println(obj.solution(37));
    }

}
Zack
  • 2,078
  • 10
  • 33
  • 58

37 Answers37

18

In Java 8, you can use stream to solve this:

static int calculateBinaryGap(int N) {
    return Stream
        .of(
            // integer to binary string
            Integer.toBinaryString(N)
                // trim 0(s) at the end
                .replaceAll("0+$", "")
                // split string with 1(s)
                .split("1+"))
        // lambda expressions: use filter to keep not null elements
        .filter(a -> a != null)
        // method references: convert string to integer by using the
        // length of string
        .map(String::length)
        // method references: find the largest number in the stream by
        // using integer comparator
        .max(Integer::compare)
        // return 0 if nothing matches after the process
        .orElse(0);
    }

There is a good article about Streams: Processing Data with Java SE 8 Streams

Fuping
  • 641
  • 1
  • 6
  • 7
7

Try this.

static int solution(int n) {
    return solution(n >>> Integer.numberOfTrailingZeros(n), 0, 0);
}

static int solution(int n, int max, int current) {
    if (n == 0)
        return max;
    else if ((n & 1) == 0)
        return solution(n >>> 1, max, current + 1);
    else
        return solution(n >>> 1, Math.max(max, current), 0);
}

and

int[] tests = { 9, 37, 0b1000001010001 };
for (int i : tests)
    System.out.printf("input = %d, Binary form = %s, Answer = %d%n",
        i , Integer.toBinaryString(i), solution(i));

output

input = 9, Binary form = 1001, Answer = 2
input = 37, Binary form = 100101, Answer = 2
input = 4177, Binary form = 1000001010001, Answer = 5

This is simple tail recursion. So you can write without recursion like this.

static int solutionLoop(int n) {
    int max = 0;
    for (int i = n >>>= Integer.numberOfTrailingZeros(n), current = 0; i != 0; i >>>= 1) {
        if ((i & 1) == 0)
            ++current;
        else {
            max = Math.max(max, current);
            current = 0;
        }
    }
    return max;
}

n >>> Integer.numberOfTrailingZeros(n) removes trailing zeros in n.

6

As many people were facing problem in handling the trailing zeros condition of the solution. Below is my solution with 100% test cases passing.

class Solution {
    public int solution(int N) {
        // write your code in Java SE 8
        return binaryGap(N,0,0,0);
    }
    public int binaryGap(int n, int counter, int max, int index){
        if(n==0)
            return max;

        if(n%2==0 && index==0)
            index=0;

        else if(n%2==0)
            counter ++;
        else {
            max = Math.max(counter, max);
            index++;
            counter =0;
        }
        n = n/2;

        return binaryGap(n, counter, max, index);
    }

}
clinton3141
  • 4,751
  • 3
  • 33
  • 46
Yoda
  • 323
  • 6
  • 14
4

We can split the binaryString with 1 as the delimiter

Eg: N=1041 BinaryString = 10000010001

When its split based on 1 as delimiter we get [, 00000, 000]

and then the subproblem becomes to find the array with largest length

private static int solution(int N) {
        int gap = 0;
        String binaryStr = Integer.toBinaryString(N);

        String[] zeroArrays = binaryStr.split("1");
        System.out.println(Arrays.toString(zeroArrays));
        for(String zeroArray : zeroArrays) {
            gap = zeroArray.length() > gap ? zeroArray.length() : gap;
        }   
        return gap;
    }
hemantvsn
  • 1,316
  • 3
  • 12
  • 24
4

My solution. 100% without recursion.

class Solution {
        public int solution(int N) {
            String binary = Integer.toString(N, 2);
            int largestGap = 0;
            for (int i = 1, gap = 0; i < binary.length(); i++) {
                while (i < binary.length() && binary.charAt(i) == '0') {
                    i++;
                    gap++;
                }

                if (gap > largestGap && i < binary.length()) {
                    largestGap = gap;
                }

                gap = 0;
            }
            return largestGap;
        }
    }
Jaumzera
  • 2,305
  • 1
  • 30
  • 44
  • is this part else { pos++; } needed? it seems there cannot be value other 0, as binary number always starts with 1, and escape from inner loop is when there is 1 value. Or it takes into account somewone type String binary manually not from parsing. – Michał Ziobro Jan 30 '18 at 18:43
  • 1
    Well @MichałZiobro ... you're right... I've made it again. – Jaumzera Feb 08 '18 at 21:38
3

This answer is tested on coditilty and it has got 100% for performance and correctness.

Hope it will help someone.

    public static int solution(int N) {
    int binaryGap = 0;

    String string = Integer.toBinaryString(N).replaceAll("0+$", "");

    String[] words = string.split("1+");

    Arrays.sort(words);

    if(words.length != 0) {
        binaryGap = words[words.length -1].length(); 
    }

    return binaryGap;

}
Mustafa Shahoud
  • 640
  • 6
  • 13
  • Welcome to Stack Overflow! Please don't answer just with source code. Try to provide a nice description about how your solution works. See: https://stackoverflow.com/help/how-to-answer. Thanks! – Matt Ke Feb 13 '19 at 00:23
2

Ruby Solution (No recursion - 100% correctness in Codility):

`

def binary_gap(number)
      remainder = []
      while number > 0
        remainder << number % 2
        number = number / 2
      end
      binary_number = remainder.reverse.join('')
      biggest_gap = 0
      current_gap = 0
      status ='stop'
      binary_number.reverse.each_char do |char|
        if char =='1'
          status = 'start'
          current_gap = 0
        elsif char == '0' && status =='start'
          current_gap +=1
        end
        if current_gap > biggest_gap
          biggest_gap = current_gap
        end
      end

      return biggest_gap

    end

`

Enow B. Mbi
  • 309
  • 3
  • 8
1

I think @saka1029 is almost there, just like @xuesheng said that solution will not work if the input for example are 2 = 010, 4 = 100, 6 = 110.

I would like to suggest do this below instead

static int solution(int n) {
    return solution(n, 0, 0, 0);
}

static int solution(int n, int max, int current, int index) {
    if (n == 0)
        return max;
    else if (n % 2 == 0 && index == 0)
        return 0;
    else if (n % 2 == 0 && index > 0)
        return solution(n / 2, max, current + 1, index + 1);
    else
        return solution(n / 2, Math.max(max, current), 0, index + 1);
}
Edi
  • 13
  • 6
1

Objective C Solution

int solution(int N) {
    if (N==0)
    {
        return 0;
    }
    int maximumGap = -1;
    int currentGap = 0;
    while(N>0)
    {
        if (N%2 == 1)
        {
            if (currentGap>0)
            {
                maximumGap = maximumGap>currentGap?maximumGap:currentGap;
            }else
            {
                maximumGap = 0;
            }
            currentGap = 0;
        }
        else if(maximumGap>-1)
        {
            currentGap++;
        }
        N=N/2;
    }
    return maximumGap;
}
Desert Rose
  • 3,376
  • 1
  • 30
  • 36
1

Java Solution (No recursion - 100% correctness in Codility):

public static int solution(Integer number) {

    String binary = Integer.toBinaryString(number);

    String[] gaps = binary.split("1");

    String biggestGap ="";
    for (int i = 0; i < (binary.endsWith("1") ? gaps.length: gaps.length-1); i++) {

        if (gaps[i].contains("0") && gaps[i].length()>biggestGap.length())
        biggestGap = gaps[i];

    }

    return biggestGap.length();
}
1

I got this solution without using recursion.

def solution(N):
    number = str(bin(N))[2:]

    current = 0
    max_ = 0
    started = False
    for e in number[::-1]:
        if e == '1':
            started = True
            if current > max_:
                max_ = current
            current = 0
        else:
            if started:
                current = current + 1
    return max_
EduardoMPinto
  • 121
  • 1
  • 6
1

The optimal solution that takes in account the boundaries and exceptional scenarios like: Given N = 32 the function should return 0, because N has binary representation '100000' and thus no binary gaps. But most code I have seen above will returns 5. Which is wrong. Here is an optimal solution that passes all tests:

public int solution(int N) {
        int result = 0;
        while (N > 0) {
            if ((N & 1) == 1) {
                int temp = 0;
                while ((N >>= 1) > 0 && ((N & 1) != 1)) {
                    temp++;
                }
                result = Math.max(result, temp);
            } else {
                N >>= 1;
            }
        }
        return result;
    } 
Maestra
  • 11
  • 1
1

My Javascript ES6 Solution with default function parameter

Also handled all possible errors

  function solution(N = 0) {
     N = +N;
     if (N !== N) {
       return 0;
     }

    const binaryList = N.toString(2).split("");
    let maxGap = 0;
    let currentGap = 0;

    binaryList.forEach(item => {
      if (item === "0") {
         current++;
      } else {
       if (currentGap > maxGap) {
          maxGap = currentGap;
       }
       currentGap = 0;
     }
   });

    return max;
  }
Ruben.sar
  • 376
  • 3
  • 11
1

def solution(N):

  max_gap = 0
  current_gap = 0

  # Skip the tailing zero(s)
  while N > 0 and N % 2 == 0:
      N //= 2

  while N > 0:
      remainder = N % 2
      if remainder == 0:
          # Inside a gap
          current_gap += 1
      else:
          # Gap ends
          if current_gap != 0:
              max_gap = max(current_gap, max_gap)
              current_gap = 0
      N //= 2

  return max_gap
if __name__ == '__main__':
    solution(N)

// Test Cases:
// N = 9 (1001), Expected = 2
// N = 529 = (1000010001), Expected = 4
// N = 51272 (1100100001001000), Expected = 4
// N = 15 (1111), Expected = 0
// N = 53 (110101), Expected = 1
// N = 2147483647 (1111111111111111111111111111111), Expected = 0
// N = 2147483648 (10000000000000000000000000000000), Expected = 0
// N = 0 (0), Expected = 0
// N = -1 (null), Expected = 0
// N = "A" (null), Expected = 0
// N = null (null), Expected = 0
// N = [blank] (null), Expected = 0
Rakesh Kumar
  • 117
  • 6
0

The solution by hemantvsn is great except the trailing zeros which need to be removed

private static int solution(int N) {
            int gap = 0;
            String binaryStr = Integer.toBinaryString(N);

            String[] zeroArrays = binaryStr.split("1");

            String[] zeroTruncated = new String[0];

            System.out.println(Arrays.toString(zeroArrays));
            if (Integer.lowestOneBit(N) != 1) {
                zeroTruncated = Arrays.copyOf(zeroArrays, zeroArrays.length-1);

            }
            for(String zeroArray : zeroTruncated) {
                gap = zeroArray.length() > gap ? zeroArray.length() : gap;
            }
            return gap;
        }
0

try this. I'm tyring without using recursive.

private static int binaryGap(int N){
    int gap1 = 0, gap2 = 0, gapCounter = 0;

    for(int i = N; i>=0; i--)
    {
        if(N < 1) break;

        //binary 0
        if(N%2 == 0) {
            gap1++;
        }
        //binary 1
        else
        {
            gap2 = gap2 > gap1 ? gap2 : gap1;
            gap1 = 0;
            gapCounter++;
        }
        if(gapCounter==1) gap2=0;
        N = N/2;
    }
    return gap2;
}
Ikhsan
  • 51
  • 1
  • 11
0
// you can write to stdout for debugging purposes, e.g.
// printf("this is a debug message\n");

int solution(int N) {
   int b;
    int zeroCounter = 0;
    int prev = 0;
    int c = -1;
    while (N) {
        b = N % 2;
        N = N / 2;
        if ((b==1)||(c==0)) {
           c=0;

            //printf("%d", b);
            if (b == 1) {

                //printf("%d", b);
                //checkTrailZero=prev;
                if (prev < zeroCounter) {
                    prev = zeroCounter;
                }
                zeroCounter = 0;
            } else {

                zeroCounter++;
            //  printf("--%d--", zeroCounter);
            }
        }
    }
    //printf("longest%d", prev);
    return prev;}
F. Atampore
  • 1
  • 1
  • 1
  • Test score codility 100% 100 out of 100 points.Programming language used: C Total time used: 70 minutes Effective time used: 70 minutes Notes: not defined yet Task timeline – F. Atampore Nov 19 '17 at 01:38
  • Welcome to SO. Please edit your additional information into the answer. Also, consider adding a few lines of explanation. – yacc Nov 19 '17 at 02:00
0

Here is working code with all the test cases passed,

package org.nishad;

import java.util.Arrays;

public class BinaryGap {
    public static void main(String[] args) {
        int N = 1;
        int result;
        //converting integer to binary string
        String NString = Integer.toBinaryString(N);
        //Removing the Trailing Zeros
        NString = NString.replaceFirst("0*$","");
        //Split the binary string by one or more one(regex) for arrays of zeros 
        String[] NStrings = NString.split("1+");
        //Storing the array length
        int length = NStrings.length;

        if(length==0) // if length is zero no gap found 
            result = length;
        else          
            {
            //Sorting the array to find the biggest zero gap
            Arrays.sort(NStrings, (a, b)->Integer.compare(a.length(), b.length()));
            result = NStrings[length-1].length();
            }


        System.out.println(NString);

        System.out.println(result);
    }
}
Nishad
  • 541
  • 3
  • 5
0

Please just do it:

class Solution {
    public int solution(int N) {
        int gap = 0;
        int current = -1;

        while(N>0) {
            if(N%2!=0) {
               if(current>gap)
                    gap = current;
                current = 0;
            } else if(current>=0){
                 current++;

            }
            N=N>>1;
            }

            return gap;
    }
}

The definitive!

Thanks!!!!

  • 1
    While this code snippet may be the solution, [including an explanation](//meta.stackexchange.com/questions/114762/explaining-entirely-‌​code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – peacetype Mar 20 '18 at 22:03
0

Javascript solution during Decimal to binary conversion.

function solution(N) {
    let maxGap = 0, currentSegmentGap = 0;

    let init = false;   

    while(N > 0) {
        const binDgt = N%2;

        if(binDgt) {
            currentSegmentGap = 0;
            init = true;

        } else if(init) {
            currentSegmentGap++;
            maxGap = maxGap > currentSegmentGap? maxGap: currentSegmentGap;
        }

        N = Math.floor(N/2);
    }
    return maxGap;
}
0

Java Solution (100% correctness in Codility)

int solution(int N) {
    int tempGap=0, gap=0;
    String binaryString = Integer.toBinaryString(N);
    int i =0;
    while(i < binaryString.length())    {
        if(binaryString.charAt(i) == '1')   {
            // initialize tempGap to hold binary gap temporarily and increment the index pointing to binary array
            ++i;
            tempGap = 0;
            // move until we encounter '1' or end of array is reached
            while(i < binaryString.length() && binaryString.charAt(i) != '1')    {
                ++i;
                tempGap++;
            }
            // in case, end of array is reached but we did not find '1'
            if (i >= binaryString.length())    {
                tempGap = 0;
            }
        } else  {
            ++i;
        }
        if (tempGap>gap)    {
            gap = tempGap;
        }
    }
    return gap;
}
Developer
  • 534
  • 1
  • 11
  • 21
0

My solution is written in Swift 4 with a totally different logic (without recursion), which finds the longest binary gap, also facilitates finding the current binary gap. 100% test cases passed.

Complexity: O(n)

public func solution(_ N : Int) -> Int {

    var arrayOfIndexes:[Int] = []
    let binaryString = String(N, radix:2)

    print("Binary String of \"\(N)\" is: \"\(binaryString)\"")

    var longestBinaryGap:Int = 0
    var index = 0

    for char in binaryString {
        if char == "1" {
            arrayOfIndexes.append(index)
            let currentBinaryGap = getCurrentBinaryGapFor(arrayOfIndexes)
            if arrayOfIndexes.count == 2 {
                longestBinaryGap = currentBinaryGap
            } else if index > 2 {
                if currentBinaryGap > longestBinaryGap {
                    longestBinaryGap = currentBinaryGap
                }
            }
        }
        index += 1
    }

    print("Position of 1's: \(arrayOfIndexes)")
    return longestBinaryGap
}

func getCurrentBinaryGapFor(_ array:[Int]) -> Int {
    var currentBinaryGap = 0
    if array.count >= 2 {
        let currentPosition = array.count - 1
        let previousPosition = currentPosition - 1
        currentBinaryGap = array[currentPosition] - array[previousPosition] - 1
        return currentBinaryGap
    } else {
        return currentBinaryGap
    }
}

Sample test cases with output:

Binary String of "2" is: "10"
Position of 1's: [0]
The longest binary gap is 0

Binary String of "4" is: "100"
Position of 1's: [0]
The longest binary gap is 0

Binary String of "6" is: "110"
Position of 1's: [0, 1]
The longest binary gap is 0

Binary String of "32" is: "100000"
Position of 1's: [0]
The longest binary gap is 0

Binary String of "170" is: "10101010"
Position of 1's: [0, 2, 4, 6]
The longest binary gap is 1

Binary String of "1041" is: "10000010001"
Position of 1's: [0, 6, 10]
The longest binary gap is 5

Binary String of "234231046" is: "1101111101100001010100000110"
Position of 1's: [0, 1, 3, 4, 5, 6, 7, 9, 10, 15, 17, 19, 25, 26]
The longest binary gap is 5
badhanganesh
  • 3,427
  • 3
  • 18
  • 39
0

@saka1029 has provided a nice solution but it does not cover all the test cases. Here is a solution that covers all cases.

public int solution(int N) {

    return solution(N, 0, 0, false);
}

static int solution(int n, int max, int count, boolean isOn) {
    if (n == 0)
        return max;
    else if (n % 2 == 0){
        count = isOn? count+1 : count;
        return solution(n / 2, max, count, isOn);
    }
    else{
        isOn=true;
        max = count>max?count:max;
        return solution(n / 2, Math.max(max, count), 0, isOn);
    }
}
0

Here is another Java solution (recursive and iterative versions) with O(log n) time complexity and 100% correctness, i.e. handling the trailing zeros condition, which avoids the use of the integer binary string.

Recursive:

class Solution {

    public int solution(int N) {
        return binaryGapRecursive(N, 0, null);
    }

    private int binaryGapRecursive(int n, int maxGap, Integer currentGap) {
        int quotient = n / 2;

        if (quotient > 0) {
            int remainder = n % 2;

            if (remainder == 1) {
                if (currentGap != null) {
                    maxGap = Math.max(maxGap, currentGap);
                }
                currentGap = 0;

            } else if (currentGap != null) {
                currentGap++;
            }

            return binaryGapRecursive(quotient, maxGap, currentGap);

        } else {
            return currentGap != null ? Math.max(maxGap, currentGap) : maxGap;
        }
    }

}

Iterative:

class Solution {

    public int solution(int n) {
        int maxGap = 0;
        Integer currentGap = null;

        while (n > 0) {
            int remainder = n % 2;

            if (remainder == 1) {
                if (currentGap != null) {
                    maxGap = Math.max(maxGap, currentGap);
                }
                currentGap = 0;

            } else if (currentGap != null) {
                currentGap++;
            }

            n = n / 2;
        }

        return currentGap != null ? Math.max(maxGap, currentGap) : maxGap;
    }

}

0

I'm tyring code

import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

public class Solution {
    public int solution(int N) {
        // write your code in Java SE 8
        int result = 0;
        // 먼저 2진수로 변환
        String binary = Integer.toBinaryString(N);
        // 첫번째 1 위치
        int firstOneIdx = 0;
        // 다음 1 위치
        int nextOneIdx = 0;

        // 전체 loop는 2진수 길이가 최대
        for (int i = 0; i <= binary.length(); i++) {

            // 첫번째만 인덱스 체크
            if (i == 0) {
                firstOneIdx = binary.indexOf("1");
            }

            // 첫번째 인덱스 다음 1 찾기
            nextOneIdx = binary.indexOf("1", firstOneIdx + 1);

            // 다음 1이 없으면 loop 나옴
            if (nextOneIdx == -1) {
                break;
            }

            // 갭
            int temp = nextOneIdx - firstOneIdx - 1;

            // 현제 갭이 이전보다 크면 결과 담음
            if (temp > result) {
                result = temp;
            }

            // 첫번째 인덱스를 이동
            firstOneIdx = nextOneIdx;
        }

        return result;
    }

    public static void main(String[] args) {
        Solution solution = new Solution();

        Random random = ThreadLocalRandom.current();

        for (int i = 0; i< 10000; i++){

            int input = random.nextInt(2147483647);
            int result = solution.solution(input);

            System.out.println("input = "+input+" result = "+result);
        }

    }
}
0

class Solution { //Java Solution (100% correctness in Codility)

public int solution(int N) {
    // write your code in Java SE 8

    Integer candidate = new Integer(N);
    String binStr = candidate.toBinaryString(N);
    char[] binArr = binStr.toCharArray();
    // System.out.println("Binary String: " + binStr);

    char c, c1;
    int counter = 0;

    for (int i = 0; i < binStr.length();) {
        // c = binStr.charAt(i);
        c = binArr[i];
        // System.out.println("c: " + c);
        i++;
        if (c == '1') {
            int tempCounter = 0;
            for (int j = 0, k = i; j < binStr.length() - 1; j++, k++) {

                if (i < binStr.length()) {
                    c1 = binArr[i];
                } else {
                    break;
                }

                // System.out.println("c1: " + c1);
                if (c1 == '1') {

                    if (counter < tempCounter)
                        counter = tempCounter;

                    break;
                } else {
                    // System.out.println("inside counter...");
                    tempCounter++;
                    i++;
                }
                // i=k;
            }
        }

    }

    // System.out.println("Counter: " + counter);
    return counter;

}

}

Ramesh J
  • 1
  • 1
0

Kotlin solution:

fun binaryGap(number: Int): Int {
    return number.toString(2)
            .trimEnd { it == '0' }
            .split("1")
            .map { it.length }
            .max() ?: 0
}
derpyderp
  • 926
  • 1
  • 10
  • 15
0

Here is the perfect solution 100 out of 100 point using Java and recursion. It did pass test of n = 128 with binary value of 10100101 and the ans. 2 and n = 592 with binary value of 1001010000 and the ans. 2.

class Solution {
    public int solution(int n) {
        return solution(n, 0, 0, 0);
    }

    static int solution(int n, int max, int current, int ones) {
        if (n == 0) {
            return max;
        } else if (n % 2 == 0) {
            return solution(n / 2, max, ++current, ones);
        } else {
            max = ones == 0 ? ones : Math.max(max, current);
            return solution(n / 2, max, 0, ++ones);
        }
    }
}

enter image description here

Luxknight007
  • 172
  • 2
  • 9
0

100% Binary Gap solution without recursion

public static int solution(int N) {

String binary = Integer.toString(N, 2);
int length = binary.length();
int trailingZeros = 0;

// Get the length of trailing zeros
for (int i = length - 1; i > 0; i--) {

  if (binary.charAt(i) == '0') {
    trailingZeros++;
  }

  else if (binary.charAt(i) == '1') {
    break;
  }
}
// length of binary string to consider
int lengthToConsider = length - trailingZeros;

System.out.println(lengthToConsider);

int highestGap = 0;
int zeroGapCount = 0;

for (int i = 1; i < lengthToConsider; i++) {
  // Count all subsequent zeros
  if (binary.charAt(i) == '0') {
    zeroGapCount++;
  }

  // else if 1 found then calculate highestGap as below
  else if (binary.charAt(i) == '1') {
    if (highestGap <= zeroGapCount) {
      highestGap = zeroGapCount;
    }
    // make the zeroGapCount as zero for next loop
    zeroGapCount = 0;
  }
}

return highestGap;

}
Anand
  • 2,239
  • 4
  • 32
  • 48
0

This is my solution in Kotlin and it got 100% on Codility

fun solution(N: Int): Int {
    var binaryGap = 0
    val string = Integer.toBinaryString(N).replace("0+$".toRegex(), "")
    val words = string.split("1+".toRegex())
                      .dropLastWhile { it.isEmpty() }
                      .toTypedArray()

    Arrays.sort(words)

    if (words.size.isNotEmpty() {
        binaryGap = words[words.size - 1].length
    }

    return binaryGap

}

Bade
  • 119
  • 1
  • 6
0

Here is my solution without recursion. 100% tests are passed in Codability's application

public class Solution {

    int counter = 0;
    Set<Integer> binaryGap = new HashSet<>();
    String binaryNumber;

    public int solution(int N) {
        binaryNumber = convert2Binary(N);

        IntStream.range(1, binaryNumber.length())
                .boxed()
                .forEach(calculateBinaryGapConsumer);

        return getMaxBinaryGap();
    }

    private String convert2Binary(int N) {
        return Integer.toBinaryString(N);
    }

    Consumer<Integer> calculateBinaryGapConsumer = i -> {
        char currentChar = binaryNumber.charAt(i);
        char previousChar = binaryNumber.charAt(i-1);
        if (previousChar == '1' && currentChar == '0') {
            increaseCounter();
        } else if (previousChar == '0' && currentChar == '0') {
            increaseCounter();
        } else if (previousChar == '0' && currentChar == '1') {
            saveBinaryGap();
            makeCounterZero();
        }
        //No need to handle case previousChar == '1' && currentChar == '1'.
    };

    private void saveBinaryGap() {
        binaryGap.add(counter);
    }

    private void increaseCounter() {
        counter++;
    }

    private void makeCounterZero() {
        counter = 0;
    }

    private int getMaxBinaryGap() {
        return binaryGap.stream().mapToInt(v->v).max().orElse(0);
    }

}
byouness
  • 1,746
  • 2
  • 24
  • 41
vlasengo
  • 1
  • 1
0

using javascript without recursion

function solution(N) {
  var binary = N.toString(2);
  var lengths = [];
  var length = -1;

  for (var i = 0; i < binary.length; i++) {
      if (
           (binary[i] === 1 && binary[i+1] === 0 && length === -1) 
           || (binary[i] === 0 && length >= 0)
         ) {
            length++;
      }
      else if (binary[i] === 1 && length >= 0) {
          lengths.push(length);
          length = -1;
          i--;
      }
  }

  return lengths.length ? Math.max(...lengths) : 0;
}
Sagar Khatri
  • 1,004
  • 8
  • 23
0

One more way

static int solution(int n) {
    String binaryNUmber = Integer.toBinaryString(n);
    char[] arr = binaryNUmber.toCharArray();

    int startIndex = -1;
    boolean found = false;
    int gap = 0;
    int newGap = 0;
    for(int i=0; i< arr.length; i++) {
        if(arr[i] == '1' && startIndex == -1) {
            startIndex = i+1;
            found = true;
            i += 1;
        }
        if(i<arr.length && found) {
            if(arr[i] == '0') {
                gap +=1;
            } else
             if(arr[i] == '1') {
                startIndex = i+1;
                if(newGap < gap) {
                    newGap  = gap;
                } 
                gap = 0;
            }
        }
    }
    return newGap;
}
Praveen Shendge
  • 303
  • 3
  • 13
0

Kotlin Solution

fun solution(N: Int): Int {
    var maxGap = 0
    var gap = 0
    for (char in N.toString(2))
        if (char == '1') {
            if (gap > maxGap) maxGap = gap
            gap = 0
        } else if (gap != -1) gap++

    return maxGap
}
DwlRathod
  • 750
  • 6
  • 17
0

This is also an extremely simple solution. This problem can also be solved by keeping track of the index where the 1 occurred(in binary). The solution does not use any array and any complex method. It is simple if else logic.

    public int solution(int N) {
    int saveN = 0;
    int digit =0;
    int value =0;
    int savedi =0;
    int resultVal =0;
    saveN = N;
    bool firstHit = true;

    //First calculate the total digits
    while(N != 0)
    {
        digit++;
        N = N / 2;
    }

    N = saveN;

    for(int i =0; i<digit;i++)
    {
        // If 1 is found at the ith place
        if((N & (0x01 << i)) == (0x01 << i))
        {
            if(firstHit)
            {
                savedi = i;// save i value
                firstHit = false;
            }
            else
            {
                value = i - savedi;
                if(resultVal < value)
                    resultVal = value;
                firstHit = true;
                // 1 found again so go 1 iteration back and save the 1's position 
                i--;
            }
        }
    }

    // sub 1 as it gives 1 more than true result  
    resultVal = resultVal - 1;

    //handle if a single 1 is found
    if(resultVal < 0)
        return 0;
    else
        return resultVal;        
}
0

My 100% JavaScript solution without using recursion:

function solution(N) {

    const binary = N.toString(2);
    let gap = 0;
    let maxGap = 0;

    for (let i = 1, len = binary.length; i < len; i++) {

        const prev = binary[i - 1];
        const cur = binary[i];

        if (prev === '1' && cur === '0') {
            gap = 1; // start counting the gap
        }
        
        if (prev === '0' && cur === '0' && gap > 0) {
            gap++; // increment the gap if the counting was previously started
        }
        
        if (prev === '0' && cur === '1' && gap > maxGap) {
            maxGap = gap; // save the gap if it is the largest
        }


    }

    return maxGap;

}
noviewpoint
  • 574
  • 1
  • 10
  • 20
-1
int solution(N) {

   int num = N,
    currentLongest=0,
    lastLongest=0,
    start=0;

  while(num>0){
    int rem = num%2;
        num = num/2;

    if(rem == 1){
        if(lastLongest < currentLongest){
            lastLongest = currentLongest;
        }
        currentLongest = 0;
        start = true;
    }else{
        if(start)
         ++currentLongest;
       }
   }
  return lastLongest;
}
Sameer
  • 509
  • 3
  • 16