在 logn 中查找排序数组中元素的频率
Find frequency of an element in sorted array in logn
这可能吗?
我想到了这个:
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) 中做这样的事情,它将如何实现?
Find frequency of an element in sorted array in logn
Is this possible?
是的。
What i did is, find first appearance of an element and the last appearance and deduct the indexes
这是一个明智的算法。
But is it O(logn)?
二分查找可以在O(log n)
中实现,在2 * O(log n) = O(log n)
中可以实现2个二分查找。因此所描述的算法可以在O(log n)
.
中实现
您的实现是否达到这种复杂性,则是另一回事。但在分析您的程序之前,请考虑其功能中的一个缺陷:如果键值最初不在 mid
点,则输出将保持不变并给出错误的结果。例如:尝试在您的示例中搜索 1
的频率。
如果您分别实现两个二进制搜索,那么分析您的算法会更容易...而且它可能还会更快,因为可以对简单的二进制搜索进行尾调用优化。
ps。无需重新实现二进制搜索。标准库已经提供了一个实现:std::lower_bound
和 std::upper_bound
(以及 std::equal_range
可以完全满足您的要求)。
我要在这里回答我自己的问题。
在伪代码中。
这可能吗? 我想到了这个:
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) 中做这样的事情,它将如何实现?
Find frequency of an element in sorted array in logn
Is this possible?
是的。
What i did is, find first appearance of an element and the last appearance and deduct the indexes
这是一个明智的算法。
But is it O(logn)?
二分查找可以在O(log n)
中实现,在2 * O(log n) = O(log n)
中可以实现2个二分查找。因此所描述的算法可以在O(log n)
.
您的实现是否达到这种复杂性,则是另一回事。但在分析您的程序之前,请考虑其功能中的一个缺陷:如果键值最初不在 mid
点,则输出将保持不变并给出错误的结果。例如:尝试在您的示例中搜索 1
的频率。
如果您分别实现两个二进制搜索,那么分析您的算法会更容易...而且它可能还会更快,因为可以对简单的二进制搜索进行尾调用优化。
ps。无需重新实现二进制搜索。标准库已经提供了一个实现:std::lower_bound
和 std::upper_bound
(以及 std::equal_range
可以完全满足您的要求)。
我要在这里回答我自己的问题。
在伪代码中。