如何在 O(log n)复杂度中构建一个返回已排序数组中给定int x的出现次数的函数?
static public int count (int [] a, int x);
我想我可能会使用二进制搜索找到第一个/最后一个外观,然后继续搜索最后/第一个外观,并返回实例数,但这是 O( log n)复杂性。
答案 0 :(得分:3)
如果你正确实现它,你的想法实际上会在时间O(log n)中起作用。进行一次二进制搜索,找到元素第一个副本的索引i,然后进行另一个二进制搜索,找到元素最后一个副本的索引j,然后返回j - i + 1.每个二进制搜索需要时间O(记录n),所以完成的工作总量是O(log n)+ O(log n)= O(log n)。
答案 1 :(得分:2)
这是我的解决方案。在有序数组中,binarySearch以log(n)步长查找数字的位置。如果该数字不存在,它将找到该数字应该位于的位置,如果它在数组中。如果搜索x + -1 / 2,那些值永远不会出现在数组中,而是会给出x的边界,因为它试图找到一个低于/高于x的值,这个值不能存在于整数数组中。比较会自动将您的整数转换为双精度,以便一切运行完美。
import java.util.ArrayList;
import java.util.List;
public class SearchCount {
public static void main(String[] args) {
final List<Integer> test = new ArrayList<Integer>();
for(int i = 1; i <= 100; i++) {
for(int j = 0; j < i && i != 50; j++) {
test.add(i);
}
}
final int[] intTest = new int[test.size()];
for (int j = 0; j < test.size(); j++) {
final int i = test.get(j);
intTest[j] = i;
}
for(int x = 0; x <= 101; x++) {
System.out.println(count(intTest,x));
}
}
public static int count (int[] a, int realKey) {
final double lowKey = realKey-0.5;
final double highKey = realKey+0.5;
final int lowerBound = binarySearch(a,0,a.length-1,lowKey);
final int upperBound = binarySearch(a,0,a.length-1,highKey);
return upperBound-lowerBound;
}
public static int binarySearch(int[] data, int low, int high, double key)
{
while(high >= low) {
final int middle = (low + high) / 2;
if(data[middle] < key) {
low = middle + 1;
}
if(key < data[middle]) {
high = middle - 1;
}
}
return high < low?low:high;
}
}