例如, 数组 A = [1, 2, 3, 4, 4,, 4, 4, 2]
输入x = 4
output: 4, 即4 重复的次数为4次
输入: 7
output: 0, 即出现了0次(没有出现)
方法一: 线性搜索: scan the whole array and count the occurrences of the number.
伪代码为:
上述的代码当然没有用到array 是sorted 这一信息。 利用sorted array 这一个信息, 我们有如下的优化后的代码:
分析:
worst case: O(n)
方法二: 更好的解决办法: 使用二叉搜索。 因为是sorted array, 很自然的想到二叉搜索。
我们只需要找到x 第一次出现的位置, 和最后一次出现的位置, 就可以得出结果。 伪代码如下:
算法复杂度: O(logn)
int BinarySearch(int A[], int n, int x) {
int low = 0, high = n - 1;
int result = -1;
while(low <= high) {
int mid = (low + high) /2;
if(A[mid] == x) {
retult = mid;
//high = mid -1; // Go on search towards left(lower indice)
low = mid + 1; //Go on searching towards right(higher indice)
}
else if(x < A[mid]) high = mid - 1;
else low = mid + 1;
}
return result;
}
由于FindFirst函数和FindLast 基本上相同的, 可能只有一行代码不同, 所以我们将其合并起来实现, 代码如下:
#include <iostream>
using namespace std;
int BinarySearch(int A[], int n, int x, bool searchFirst) {
int low = 0, high = n - 1;
int result = -1;
while(low <= high) {
int mid = (low + high) /2;
if(A[mid] == x) {
result = mid;
if(searchFirst) {
high = mid -1; // Go on search towards left(lower indice)
}
else {
low = mid + 1; //Go on searching towards right(higher indice)
}
}
else if(x < A[mid]) high = mid - 1;
else low = mid + 1;
}
return result;
}
int main() {
int A[] = {1, 2, 3, 5, 5, 5, 5, 5, 6};
int x = 0;
cin >> x;
int firstIndex = BinarySearch(A, sizeof(A)/sizeof(A[0]), x, true);
if (firstIndex == -1) {
cout << "not exist" << endl;
}
else {
int lastIndex = BinarySearch(A, sizeof(A)/sizeof(A[0]), x, false);
cout << "count: " << lastIndex - firstIndex + 1<< endl;
}
return 0;
}
运行结果如下: