在logn中查找已排序数组中元素的频率

时间:2016-02-23 20:25:54

标签: c++ complexity-theory

这可能吗? 我想出了这个:

void binary_search(int list[], int lo, int hi, int key, int* maxIndex, int* minIndex) {
    int mid;
    if (lo > hi) {
        printf("Key not found\n");
        return;
    }
    mid = (lo + hi) / 2;
    if (list[mid] == key) {
        counter++;
        if (*maxIndex == -1) {
            *maxIndex = mid;
            cout << "Init max" << endl;
        }
        if (mid > *maxIndex) {
            *maxIndex = mid;
            cout << "Change max" << endl;
        }

        if (*minIndex == -1) {
            *minIndex = mid;
            cout << "Init min" << endl;
        }

        if (mid < *minIndex) {
            *minIndex = mid;
            cout << "Change min" << endl;
        }
    }
    if (mid - 1 >= 0)
        if (list[mid - 1] == key)
            binary_search(list, lo, mid - 1, key, maxIndex, minIndex);
    if (mid + 1 <= hi)
        if (list[mid + 1] == key)
            binary_search(list, mid + 1, hi, key, maxIndex, minIndex);
}



int main() {
    int min = 10;
    int max = -1;
    int arr[] = { 1,1,3,3,3,3,4,7,8,9 };

    binary_search(arr, 0, 10, 3, &max, &min);
    cout << max - min + 1 << endl;
    cout << counter;
    return 0;
}

我做的是,找到元素的第一次出现和最后一次出现并扣除索引,但是它是O(logn)吗?

最坏的情况似乎是O(n),因为最坏情况下的递归公式是T(n)= 2T(n / 2)= O(n);

我的问题是,是否可以在O(logn)中执行此类操作,以及如何实现?

2 个答案:

答案 0 :(得分:2)

  

在logn

中查找已排序数组中元素的频率      

这可能吗?

  

我做的是,找到元素的第一次出现和最后一次出现并扣除索引

这是一个明智的算法。

  

但是O(logn)?

可以在O(log n)中实现二进制搜索 ,并且可以在2 * O(log n) = O(log n)中实现2个二进制搜索。因此,所描述的算法可以在O(log n)中实现。

您的实施是否实现了这种复杂性,这是另一回事。但在分析程序之前,请考虑它的功能缺陷:如果键值最初不在mid点,则输出将保持不变并给出错误的结果。例如:尝试在您的示例中搜索1的频率。

如果单独实施两个二进制搜索,分析算法会更容易......而且它可能也会更快,因为简单的二进制搜索可以进行尾调用优化。

PS。没有必要重新实现二进制搜索。标准库已经提供了一个实现:std::lower_boundstd::upper_bound(以及std::equal_range,它可以完全满足您的要求。

答案 1 :(得分:0)

我会在这里回答我自己的问题。 array

在伪代码中。