Java 用递归法求解二进制间隙

Java 用递归法求解二进制间隙,java,algorithm,recursion,binary,time-complexity,Java,Algorithm,Recursion,Binary,Time Complexity,我正在尝试使用递归来解决二进制间隙问题。无需递归即可轻松求解。但我想用递归来解决这个问题。下面的程序以一个整数作为输入,并找到二进制间隙 例如: input= 9, Binary form = 1001, Answer = 2 input=37, Binary form = 100101, Answer = 2 它查找二进制表示中两个1之间出现的最大零数 我想用O(logn)来解决这个问题。现在,下面的程序只是计算零的总数,并给出输出3而不是2。如何更正此错误以获得正确的输出 class B

我正在尝试使用递归来解决二进制间隙问题。无需递归即可轻松求解。但我想用递归来解决这个问题。下面的程序以一个整数作为输入,并找到二进制间隙

例如:

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

input=37, Binary form = 100101, Answer = 2
它查找二进制表示中两个1之间出现的最大零数

我想用O(logn)来解决这个问题。现在,下面的程序只是计算零的总数,并给出输出3而不是2。如何更正此错误以获得正确的输出

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

}
classbinaryGap{
公共int解决方案(int N){
返回溶液(N,false,0);
}
公共int解决方案(int N、布尔prevFlag、int memo){
if(N备忘录)
memo=newGap;
}
}否则{
prevFlag=(余数==1);
返回溶液(N/2,prevFlag,0);
}
返回备忘录;
}
公共静态void main(字符串参数[]){
BinaryGap obj=新的BinaryGap();
系统输出打印LN(对象解决方案(37));
}
}
试试这个

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

输出

input = 9, Binary form = 1001, Answer = 2
input = 37, Binary form = 100101, Answer = 2
input = 4177, Binary form = 1000001010001, Answer = 5
这是简单的尾部递归。所以你可以这样写而不用递归

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)
删除
n

中的尾随零在Java 8中,您可以使用stream来解决此问题:

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

有一篇关于Streams的好文章:

我们可以用1作为分隔符拆分binaryString

例如: N=1041 BinaryString=100000001

当它以1作为分隔符进行拆分时 我们得到[00000000]

然后子问题变成寻找长度最大的数组

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

我觉得@saka1029就快到了,就像@xuesheng说的,如果输入是2=010,4=100,6=110,这个解决方案就不起作用了

我建议改为在下面这样做

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

hemantvsn的解决方案非常好,除了需要删除的尾随零

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

因为许多人在处理解决方案的尾随零条件时面临问题。 下面是我100%通过测试用例的解决方案

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

}
目标C溶液

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

我的解决方案。100%无递归

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;
        }
    }
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_
类解决方案{
公共int解决方案(int N){
字符串二进制=整数.toString(N,2);
int-largestGap=0;
对于(inti=1,gap=0;ilargestGap&&i
试试这个。我没有使用递归的轮胎

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;
}
私有静态int-binaryGap(int-N){
int gap1=0,gap2=0,gapCounter=0;
对于(int i=N;i>=0;i--)
{
如果(N<1)断裂;
//二进制0
如果(N%2==0){
gap1++;
}
//二进制1
其他的
{
gap2=gap2>gap1?gap2:gap1;
gap1=0;
gapCounter++;
}
如果(gapCounter==1)gap2=0;
N=N/2;
}
返回gap2;
}
//您可以出于调试目的写入stdout,例如。
//printf(“这是一条调试消息\n”);
整数解(整数N){
int b;
int零计数器=0;
int prev=0;
int c=-1;
while(N){
b=N%2;
N=N/2;
如果((b==1)| |(c==0)){
c=0;
//printf(“%d”,b);
如果(b==1){
//printf(“%d”,b);
//checkTrailZero=prev;
如果(上一个<零计数器){
prev=零计数器;
}
零计数器=0;
}否则{
零计数器++;
//printf(“--%d--”,零计数器);
}
}
}
//printf(“最长%d”,上一个);
返回prev;}

这里是所有测试用例都通过的工作代码

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);
    }
}
Java解决方案(无递归-编码正确率100%):

公共静态int解决方案(整数){
字符串二进制=整数。toBinaryString(数字);
String[]gaps=binary.split(“1”);
字符串biggestGap=“”;
对于(int i=0;i<(binary.endsWith(“1”)?gaps.length:gaps.length-1);i++){
if(gaps[i].包含(“0”)&&gaps[i].length()>biggestGap.length())
最大间隙=间隙[i];
}
返回biggestGap.length();
}
请直接做:

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


谢谢

十进制到二进制转换期间的Javascript解决方案

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;
}
Java解决方案(编码正确率100%)

int解决方案(int N){
int tempGap=0,gap=0;
String binaryString=Integer.toBinaryString(N);
int i=0;
而(i=binaryString.length()){
tempGap=0;
}
}否则{
++一,;
}
如果(临时间隙>间隙){
gap=tempGap;
}
}
返回间隙;
}

我没有使用递归就得到了这个解决方案

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

我的解决方案是用Swift 4编写的,具有完全不同的逻辑(无递归),它可以找到最长的二进制间隔,也有助于找到当前的二进制间隔。100%的测试用例通过

复杂性:O(n)

输出为的样本测试用例:

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

}
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;
    }
fun binaryGap(number: Int): Int {
    return number.toString(2)
            .trimEnd { it == '0' }
            .split("1")
            .map { it.length }
            .max() ?: 0
}

@saka1029提供了一个很好的解决方案b
    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);
    }
}
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;
    } 
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;
        }
    }

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

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

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

}
fun binaryGap(number: Int): Int {
    return number.toString(2)
            .trimEnd { it == '0' }
            .split("1")
            .map { it.length }
            .max() ?: 0
}
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);
        }
    }
}
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;

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

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