确定二进制数的间隙长度

时间:2016-03-08 21:25:17

标签: java algorithm arraylist

我正在尝试进行以下练习(在Codility上找到):

enter image description here

我接近它的方法是使用指针。例如。 25的二进制表示是11001.我们从i = 0,j = 1开始,变量gLength = 0,跟踪间隙的长度。

如果第i个索引为1,请检查第j个索引。如果第j个索引为0,则递增gLength。如果第j个索引是1,检查gLength是否大于0.如果是,那么我们需要将这个长度存储在ArrayList中,因为我们已经到达了差距的末尾。增加i和j,然后重复。

这是代码中的方法:

public static int solution(int N) {
    String binaryStr = Integer.toBinaryString(N);
    // pointers
    int i = 0;
    int j = 1;
    // length of gap
    int gLength = 0;

    while (j < binaryStr.length() && i < j) {
        if (binaryStr.charAt(i) == 1) {
            if (binaryStr.charAt(j) == 0) {
                gLength++; // increment length of gap 
            } else if (binaryStr.charAt(j) == 1) {
                // if the digit at the j'th position is the end of a gap, add the gap size to list. 
                if (gLength > 0)
                    gapLengths.add(gLength);
                i++; // increment i pointer
            }
        } else {
            i++; // increment i pointer
        }
        j++; // increment j pointer
    }

    Collections.sort(gapLengths);
    // Line 45 (ERROR)
    int maxGap = gapLengths.get(gapLengths.size() - 1);
    return maxGap;
}

我收到以下错误:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.ArrayList.elementData(ArrayList.java:400)
at java.util.ArrayList.get(ArrayList.java:413)
at Codility.solution(Codility.java:45)
at Codility.main(Codility.java:15)

我已经在评论中标记了第45行的位置。在进一步调查(使用调试器)之后,我发现我得到了错误,因为似乎没有长度添加到ArrayList。有人知道为什么吗?

我希望这很清楚,如果不是,请告诉我。我不确定这个方法是否会像O(log n)时间那样执行,但是现在我只想要有一些工作 - 然后我会考虑它的时间复杂性方面。

非常感谢任何帮助。

5 个答案:

答案 0 :(得分:2)

问题是if (binaryStr.charAt(i) == 1)。您正在将charint进行比较。

<强>替换

if (binaryStr.charAt(i) == 1)

if (binaryStr.charAt(j) == 0)

使用:

if (binaryStr.charAt(i) == '1')

if (binaryStr.charAt(j) == '0')

修改(正如Andy指出的那样)

在执行int maxGap = gapLengths.get(gapLengths.size() - 1);之前,您需要检查if gapLengths.size() > 0以确保ArrayList中至少有1个元素。

答案 1 :(得分:1)

我不想烦恼,我认为这些人为你的算法提供了很大的帮助。我建议,我相信这是一种更容易使用的方法

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

然后继续检查数组的最大元素。

编辑:显然我错过了关于大O限制的部分,所以我使用了不同的算法: 如果你看看这个页面http://www.convertbinary.com/numbers.php 你会注意到差距从5(0差距)然后是9(00差距)然后是17(000差距)等开始。(按递增顺序),我注意到的快速关系是你从5开始然后添加(5-1 = 4)你得到00的差距为9,然后9 + 8 = 17(000差距)等。

我相信你可能能够提出一个固定的计算来获得最佳性能而无需做String或Char工作。

答案 2 :(得分:0)

Swift中的一个简单解决方案:

let number = 5101
let binrygap = String(num, radix:2).componentsSeparatedByString("1").map { (a) -> Int in
a.characters.count}.maxElement()

答案 3 :(得分:0)

简单解决方案100%

System.Diagnostics

答案 4 :(得分:0)

Java 8实现。

`

class Solution {
    public int solution(int N) {
        while(N%2 == 0){
            N /= 2;
        }
        String binaryString = Integer.toBinaryString(N);
        String[] matches = binaryString.split("1");
        Optional maxValueOptional = Arrays.stream(matches).max(String::compareTo);
        return maxValueOptional.isPresent()? ((String) maxValueOptional.get()).length():0;
    }
}

`