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

守給你的承諾、 提交于 2019-12-03 22:00:16

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;
}

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;
}

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;
    }

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++;

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);
}

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;
}

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;
   }
}

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;
}

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;
}
benjamin palma

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;
    }
}

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 ;
    }

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();
}

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