Is my code solution for Binary Gap is correct or not? What should I improved in that?

落花浮王杯 提交于 2019-12-05 08:18:39

问题


A binary gap within a positive integer N is any maximal sequence of consecutive zeros that is surrounded by ones at both ends in the binary representation of N.

For example, number 9 has binary representation 1001 and contains a binary gap of length 2. The number 529 has binary representation 1000010001 and contains two binary gaps: one of length 4 and one of length 3. The number 20 has binary representation 10100 and contains one binary gap of length 1. The number 15 has binary representation 1111 and has no binary gaps.

Write a function:

int solution(int N); that, given a positive integer N, returns the length of its longest binary gap. The function should return 0 if N doesn't contain a binary gap.

For example, given N = 1041 the function should return 5, because N has binary representation 10000010001 and so its longest binary gap is of length 5.

public int solution(int n) {
        // write your code in Java SE 8
        String binaryRep = Integer.toBinaryString(n);
        System.out.println("Binary Representation of " + n + " = " + binaryRep);
        List<String> strList = new ArrayList<String>();
        int count = 0;
        for (int i = 0; i < binaryRep.length(); i++) { // Loop through the each number 
            String str = binaryRep.charAt(i) + ""; // getting one by one number
            if(str.equals("0")){
                for(int j = i;j<binaryRep.length();j++){ //Get each next element
                    String str1 = binaryRep.charAt(j) + "";
                    if(!str.equals("1") &&  str.equals(str1)){
                        if(!strList.isEmpty() && count >= strList.size()){
                            strList.add(str1);
                        }else if(strList.isEmpty()){
                            strList.add(str1);
                        }
                        count ++; 
                    }else{
                        count = 0;
                        break;
                    }
                }
           }   
        }
        return strList.size();
    }

回答1:


I haven't tested your code yet, but it seems very inefficient if your goal is just counting the longest 'binary gap'.

Problems in your code:

  • Makes java.lang.String when it can be just char. Making objects is much slower than making primitive types.
  • Makes a list when it's able to simply count. As long as you're only going to need size of the list, you can just count it in a integer variable.
  • Stupid algorithm. A substring of a string can't be longer than the original one. I'm talking about the second for loop. For example, let's say you're counting binary gap of 1001. Then your algorithm counts binary gap of 001 and then 01. You don't need to count the second one at all. And it's happening becuase you have two for loops.

The biggest problem is, that it's possible to solve this problem without converting int into java.lang.String at all. And in case you got this problem from a textbook, I believe this is the 'correct' answer: To use bitwise operators.

public static int solution(int num) {
    int ptr; //Used for bitwise operation.
    for(ptr=1; ptr>0; ptr<<=1) //Find the lowest bit 1
        if((num&ptr) != 0)
            break;
    int cnt=0; //Count the (possible) gap
    int ret=0; //Keep the longest gap.
    for(; ptr>0; ptr<<=1) {
        if((num&ptr) != 0) { //If it's bit 1
            ret = cnt < ret ? ret : cnt; //Get the bigger one between cnt and ret
            cnt=-1; //Exclude this bit
        }
        cnt++; //Increment the count. If this bit is 1, then cnt would become 0 beause we set the cnt as -1 instead of 0.
    }
    return ret;
}



回答2:


There is no need to place the contents of the binary string into an Array (unless of course this is a requirement), simply iterate through the string itself and use the String.substring() method to retrieve the string represented value of each binary digit, as in:

String digit = binaryString.substring(i, i+1);

It all boils down to counting the number of 0's between any set of 1's and keeping track of those 0's by using a Integer data type variable that is incremented every time a 0 is encountered. This same variable is reset to 0 every time a 1 is encountered but before it's reset you would compare it to yet another predefined Integer variable which would hold the longest run of 0's encountered, for example:

if(binaryString.substring(i, i+1).equals("1")) {
    if (zeroHit > longest) { longest = zeroHit; }
    zeroHit = 0;
}
else { zeroHit++; }

The whole method might look something like this:

private static int solution(int intValue) {
    String binaryString = Integer.toBinaryString(intValue);
    int zeroHit = 0;
    int longest = 0;
    for (int i = 0; i < binaryString.length(); i++) {
        if(binaryString.substring(i, i+1).equals("1")) {
            if (zeroHit > longest) { longest = zeroHit; }
            zeroHit = 0;
        }
        else { zeroHit++; }
    }
    return longest;
}



回答3:


Here is my modest solution. Now I see that it's looks like modification of DevilsHnd answer. I tested it

public int countZeros(int n) {
        String binaryRep = Integer.toBinaryString(n);
        char[] nChars = binaryRep.toCharArray();
        int nElemLength = Math.min(binaryRep.lastIndexOf('1') + 1, nChars.length);
        if (nElemLength <= 2) {
            return 0;
        }
        String[] elementsParts = binaryRep.substring(0, nElemLength).split("1");
        int zeroLength = 0;
        for (String elementsPart : elementsParts) {
            if (elementsPart.length() > zeroLength) {
                zeroLength = elementsPart.length();
            }
        }
        return zeroLength;
    }



回答4:


What about this algorithm. Is it bad for time performance or good?

int count = 0, prevCount = 0;

while (a > 1) {

  if (a % 2 == 0) {
     count++;
     if (count > prevCount)
        prevCount++;
     } else {
            count = 0;
        }    
        a = a/2;
    }

    if(a % 2 == 0)
       prevCount++;



回答5:


I think your code is a little bit confusing,check this one.

public int solution(int n) {
    if (n <= 0) return 0;
    char[] chars = Integer.toBinaryString(n).toCharArray();
    ArrayList<Integer> arrayList = new ArrayList<>();
    int maxCount = 0;
    for (int i = 0; i < chars.length; i++) {
        while (chars[i] == '0' && i + 1 < chars.length) {
            maxCount++;
            i++;
            if (i + 1 == chars.length && chars[i] == '0')
                maxCount = 0;
        }
        if (maxCount != 0)
            arrayList.add(maxCount);
        maxCount = 0;
    }

    return arrayList.isEmpty() ? 0 : Collections.max(arrayList);
}



回答6:


Hi this is my solution for this task. I had Task Score : 100% Correctness : 100%

public int solution(int N) {
    String binary = Integer.toBinaryString(N);
    int[] table = new int[binary.length()];

    for (int i=0;i<binary.length();i++){
        int number = Integer.parseInt(binary.substring(i,i+1));
        table[i] = number;
    }

    int resu = 0;
    int res = 0;
    for (int i=0;i<table.length;i++){
        if (table[i] == 1){
            if (resu > res){
                res = resu;
            }
            resu = 0;
        }else {
            resu++;
        }
    }

    return res;
}



回答7:


For the benefit of all, here is my solution to the Binary Gap which got me 100% for both Task Score and Task Correctness:

class Solution {
    public int solution(int N) {
        String nStr = Integer.toBinaryString(N);

        boolean isCounting = false;
        int j=0;
        int[] seqs = new int[32];
        for (int i=0; i<nStr.length(); i++)
        {
            if ( nStr.charAt(i) == '1')
            {
                if (!isCounting)
                {
                    isCounting = true;
                    seqs[j] = 0;
                }
                else // isCounting, turn it off
                {
                    isCounting = false;
                    j++;
                }

            }
            else // nStr.charAt(i) == '0'
            {
                if (!isCounting)
                    isCounting = true;
                seqs[j]++;
            }

        }
        if (isCounting == true)
            seqs[j] = 0;

        int maxGap = 0;
        for (int k=0; k<seqs.length; k++)
            if (seqs[k] > maxGap)
                maxGap = seqs[k];
        return maxGap;
   }
}



回答8:


OBJECTIVE-C SOLUTION O(2n)

Results given by Codility

Task Score: 100%
Correctness: 100%
Performance: Not assesed

Time Complexity

The worst case time complexity is O(2n)

Algorithm Explanation

FACTS

Every valid gap starts with a '1' and close with another '1', with at least one 'zero' between them.

  • 1001 - Is a valid gap
  • 00100 - Isn't a valid gap
  • 10100 - Is a valid gap
  • 11111 - Isn't a valid gap

STEP 1

  • Get the bits of n, using an auxiliary method wich has O(n) Complexity

STEP 2

  • Iterate over each bit we got in Step One
  • Start looking for the first '1' - since our flag 'hasStartPattern' is false in the first iteration, we'll look for the first occurrence of '1', that means we have a valid start pattern and we change the flag 'hasStartPattern' to true for the next iterations we should validate if the current bit is '0' and use a counter, in this case 'candidates'.
  • Only if, there is another '1' in the incoming bits, we are sure that we have a valid binary gap, then we compare our previous 'candidates' with our current 'gapCounter' in order to keep the highest one.
  • In case that there isn't another '1' to close the gap, we never change the value of 'gapCounter' and we return 0.

Xcode Solution Here

+(int)solutionTwo:(int)n {    
    // STEP 1
    // O(n)
    NSString *bits = [self getBitsForNumber:n];

    BOOL hasStartPattern = NO;
    int candidates = 0;
    int gapCounter = 0;

    // STEP 2
    // O(n)
    for (int i=0; i < bits.length; i++) {

        char currentBit = [bits characterAtIndex:i];

        if ( hasStartPattern  && currentBit == '0' ) {
            candidates++;
        }
        else if ( hasStartPattern  && currentBit == '1' ) {
            // At least one '1' exist as a close pattern
            if (candidates > gapCounter) {
                gapCounter = candidates;
            }
            candidates = 0;
        }
        else if (currentBit == '1') {
            hasStartPattern = YES; // At least one '1' exist as an open pattern
        }

    }

    return gapCounter;
}

/*
Time Complexity:
- The worst case time complexity for this auxiliary method is O(n)
*/
+(NSString*)getBitsForNumber:(int)n {
    NSMutableString *bits = [NSMutableString string];
    while(n) {
        [bits insertString:((n&1)? @"1" : @"0") atIndex:0];
        n /= 2;
    }
    return bits;
}



回答9:


OBJECTIVE-C SOLUTION O(n)

Results given by Codility

Task Score: 100%
Correctness: 100%
Performance: Not assesed

Time Complexity

The worst case time complexity is O(n)

Algorithm Explanation

FACTS

Every valid gap starts with a '1' and close with another '1', with at least one 'zero' between them.

  • 1001 - Is a valid gap
  • 00100 - Isn't a valid gap
  • 10100 - Is a valid gap
  • 11111 - Isn't a valid gap

STEP 1

  • Get bits representation one by one from the Rigth to the Left.

  • That means, for n=4, I'll get first a Zero, then another Zero, then a One, finally a Zero. [0,1,0,0]

  • 4 -> 0100

STEP 2

  • Start looking for the first '1' - since our flag 'hasStartPattern' is false in the first iteration, we'll look for the first occurrence of '1', that means we have a valid start pattern and we change the flag 'hasStartPattern' to true for the next iterations we should validate if the current bit is '0' and use a counter, in this case 'candidates'.

  • Only if, there is another '1' in the incoming bits, we are sure that we have a valid binary gap, then we compare our previous 'candidates' with our current 'gapCounter' in order to keep the highest one.

  • In case that there isn't another '1' to close the gap, we never change the value of 'gapCounter' and we return 0

Xcode Solution Here

-(int)solutionOne:(int)n {

    BOOL hasStartPattern = NO;
    int candidates = 0;
    int gapCounter = 0;

    while(n){
        // STEP 1
        NSString *bit = (n & 1) ? @"1": @"0";
        n /= 2;

        // STEP 2
        if ( hasStartPattern  && [bit isEqualToString:@"0"]) {
            candidates++;
        }
        else if ( hasStartPattern  && [bit isEqualToString:@"1"]) {
            // At least one '1' exist as a close pattern
            if (candidates > gapCounter) {
                gapCounter = candidates;
            }
            candidates = 0;
        }
        else if ([bit isEqualToString:@"1"]) {
            hasStartPattern = YES; // At least one '1' exist as an open pattern
        }
    }
    return gapCounter;
}



回答10:


here is my solution.

It is 100/100.

I think it can be polished though.

    class Solution {
      public int solution(int N) {

       String s = Integer.toBinaryString(N);
       int ctr = 0;

       for (int x = 0; x < s.length(); x++){

           if (s.substring(x,x+1).equals("1")){

               ctr++;
           }

       }


       int result[] = new int[ctr];

       boolean flag = false;
       int fCtr = 0;
       for(int y = 0; y < s.length(); y++){
           if(s.substring(y,y+1).equals("1")){
               flag = true;
               if(flag == true){
                    fCtr++;
               }

               }
           else if (s.substring(y,y+1).equals("0") && flag == true && fCtr < ctr){
               result[fCtr]++;
           }
         } 

        int ans = 0;
        for (int d = 0; d < result.length; d++){
            if (ans <= result[d]){
                ans = result[d];
            }
        }

       return ans;
    }
}



回答11:


I think this one is a very small code

    public int solution(int N)
    {
        string binary = Convert.ToString(N, 2);
        binary = binary.TrimEnd(new Char[] { '0' });
        var gaps = binary.Split('1');
        int max = 0;
        foreach (var item in gaps)
        {
            if (!string.IsNullOrEmpty(item))
                if(item.Length > max)
                   max = item.Length;
        }            
        return max ;
    }



回答12:


here mine

public int solution(int N) {

    String binary = Integer.toBinaryString(N);

    LinkedList<Integer> gaps = new LinkedList<>();
    int countGap = 0;
    int j = 0;
    for (int i = 1; i < binary.length() - 1; i++) {
        if (binary.charAt(i) == '0') {
            countGap++;
        } else {

            gaps.add(j, countGap);
            j++;
            countGap = 0;
        }
    }

    gaps.add(j, countGap);

    if (binary.charAt(binary.length() - 1) == '0') {
        gaps.set(gaps.size() - 1, 0);
    }

    Collections.sort(gaps);

    return gaps.getLast();
}



回答13:


Here is my solution. (Scala)

It is 100/100.

 object Solution {
  def solution(n: Int): Int = {
   val regex = raw"(?=(10*1))".r
   val result = regex.findAllMatchIn(n.toBinaryString).map(_.group(1)) match {
    case re:Iterator[String] if !re.isEmpty => (re.toList.map(Integer.parseInt(_, 2)).sorted.last.toBinaryString.length - 2)
    case _ => 0
  }
  result
  }
}


来源:https://stackoverflow.com/questions/40946025/is-my-code-solution-for-binary-gap-is-correct-or-not-what-should-i-improved-in

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!