访谈主题:二进制搜索范围

时间:2017-11-08 20:54:30

标签: java binary-search

我感到有点沮丧,因为他们没有雇用我没有达到目标,但我认为这是不可能的。

问题: “给定一个带有排序数据的数组,例如   0,1,2,4,4,6,7,7,7,7,8,9,10,12,15,15 编写一个在O(log(n))中实现二进制搜索的java类,以查找元素X的所有实例(例如X = 7),以及随附的JUnit单元测试。如果元素至少找到一次,则返回所有索引;如果未找到,则返回-1。在解决此问题时,明确指出您正在做出的任何假设。

我找到了在log(n)时间内获取元素的左索引和右索引的方法。

但是你怎么能在log(n)时间内返回所有指数,任何想法?

3 个答案:

答案 0 :(得分:1)

在最糟糕的情况下,例如如果列表都是“7”,@ Duarte Meneses向外走去寻找两端的方法将采用O(n),而不是O(log n)。

如果通过二分查找找到两端(如OP所说),只需将索引返回到两端,那就是O(log n)。

但是如果提问者在他们要求你“返回所有索引”时准确地排除那个,那么在最坏的情况下你不能这样做,因为要返回的不仅仅是log n项,而只是制作要返回的列表需要比O(log n)更长的时间 - 即使你在0时间内神奇地找到它们。

答案 1 :(得分:1)

我不打算为你实现binarySearch,因为你可以在网上找到许多代码示例。相反,一旦你找到了你正在寻找的数字的一个指数,我将展示你能做些什么:

算法很简单,你向后迭代直到你到达第一个出现的数字,然后迭代并将所有索引添加到结果列表中。

public static void main(String[] args) {
    int[] arr = {0, 1, 2, 4, 4, 6, 7, 7, 7, 7, 8, 9, 10, 12, 15, 15 };
    List<Integer> indices = findIndices(arr, 7);
    System.out.println(indices);
}

static List<Integer> findIndices(int[] arr, int num) {
    // here we may have one of the indices of 7: [6, 7, 8, 9]
    int index = Arrays.binarySearch(arr, num);
    List<Integer> result = new LinkedList<>();

    if (index < 0) { // not found
        result.add(-1);
    } else {  // found, now go backwards till the first one
        while (index > 0 && arr[index-1] == num) {
            index--;
        }
        // add all indices to the result-list
        while (arr[index] == num) {
            result.add(index++);
        }
    }
    return result;
}

答案 2 :(得分:0)

使用二进制搜索查找元素的索引将花费log(n)时间。由于数组已排序,您可以打印出该索引旁边的元素。这应该采用log(n)+ k,其中k是出现次数,并且应该仍然是log(n),这取决于搜索元素出现的次数。