题目:统计一个数字在排序数组中出现的次数。例如,输入排序数组{1,2,3,3,3,4,5,6}和数字3,由于3在数组中出现了3次,因此输出次数3。
方案一:时间复杂度为O(n)
- 先用二分查找找到3;
- 在3的两边顺序扫描,分别找出第一个3和最后一个3的位置;
- 最后用最后一个3的位置减去第一个3的位置加1,就能得出3在数组中的个数。
方案二:时间复杂度为O(log2(n))
- 先用二分查找的方法找到3;
- 然后再用二分查找的方法找到第一个3和最后一个3的位置;
- 最后用最后一个3的位置减去第一个3的位置加1,就能得出3在数组中出现的次数。
方案二与方案一相同的是:都用二分查找找到第一个3;
方案一与方案二不同的是:方案一用顺序查找的方法找到3的首尾位置,而方案二用二分查找的方法找到3的首尾位置。
程序如下:
#include<stdio.h>
#include<stdlib.h>
//向查找数的前面查找,获取第一个查找数的位置
int GetFirstIndex(int arr[], int len, int K, int start, int end)
{
//避免栈溢出
if (start > end)
{
return -1;
}
//求中间数
int mid = start + ((end - start) >> 1);
//当中间值等于查找数时
if (arr[mid] == K)
{
//当查找数与前面一个元素的值不相同时,返回此时的下标
if ((mid > 0 && arr[mid - 1] != K) || mid == 0)
{
return mid;
}
//当查找数与前面一个元素的值相同时,则继续向前查找
else
{
end = mid - 1;
}
}
//当中间值大于查找值时
else if (arr[mid] > K)
{
end = mid - 1;
}
//当中间值小于查找值时
else
{
start = mid + 1;
}
//递归调用
GetFirstIndex(arr, len, K, start, end);
}
//向查找数的后面查找,获取最后一个查找数的位置
int GetLastIndex(int arr[], int len, int K, int start, int end)
{
//递归出口,避免栈溢出
if (start > end)
{
return -1;
}
//求中间数
int mid = start + ((end - start) >> 1);
//当中间值与查找数相等时
if (arr[mid] == K)
{
//当查找数与后面一个元素的值不相同时,返回此时的下标
if ((mid < len - 1 && arr[mid + 1] != K) || mid == len - 1)
{
return mid;
}
当查找数与后面一个元素的值相同时,则继续向后查找
else
{
start = mid + 1;
}
}
//当中间值大于查找数时
else if (arr[mid] > K)
{
end = mid - 1;
}
//当中间值小于查找数时
else
{
start = mid + 1;
}
//递归调用
GetLastIndex(arr, len, K, start, end);
}
int GetTimesOfK(int arr[], int len, int K)
{
//处理异常情况
if (arr == NULL || len <= 0)
{
return -1;
}
int first = GetFirstIndex(arr, len, K, 0, len - 1);//获取第一个查找数的位置
int last = GetLastIndex(arr, len, K, 0, len - 1);//获取最后一个查找数的位置
int count = 0;//创建一个变量标记查找数在数组中出现的次数
if (first > -1 && last > -1)
{
count = last - first + 1;//注意:查找数的位置差加1才是查找数在数组中出现的次数
}
return count;
}
int main()
{
int arr[] = { 1, 2, 3, 3, 3, 4, 5, 6 };
int len = sizeof(arr) / sizeof(arr[0]);
int k = 3;
for (int i = 0; i < len; i++)
{
printf("% d", arr[i]);
}
printf("\n");
int ret = GetTimesOfK(arr, len, k);
printf("%d在数组中出现的次数是% d\n",k, ret);
system("pause");
return 0;
}
运行结果: