我感到有点沮丧,因为他们没有雇用我没有达到目标,但我认为这是不可能的。
问题: “给定一个带有排序数据的数组,例如 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)时间内返回所有指数,任何想法?
答案 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),这取决于搜索元素出现的次数。