以O(log n)复杂度计算排序数组中值的出现次数

时间:2016-01-05 18:03:36

标签: java arrays algorithm search complexity-theory

如何在 O(log n)复杂度中构建一个返回已排序数组中给定int x的出现次数的函数?

static public int count (int [] a, int x);

我想我可能会使用二进制搜索找到第一个/最后一个外观,然后继续搜索最后/第一个外观,并返回实例数,但这是 O( log n)复杂性。

2 个答案:

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