题目:
统计一个数字在排序数组中出现的次数,例如输入排序数组{1,2,3,3,3,3,4,5};和数字3,由于3在数组中出现了4次,因此输出4.
思路:
时间复杂度:
O(logn)
空间复杂度:
O(1)
int FindFirstK(int* arr, int k, int left, int right) //找第一个k的位置
{
if (left > right) //闭区间
{
return -1;
}
int mid = left + ((right - left) >> 1);
if (arr[mid] == k)
{
if (((mid - 1 >= 0) && (arr[mid - 1] != k)) || mid == 0)
{
return mid; //此时为mid下标的即为第一个k值
}
right = mid - 1; //二分法
}
else if (arr[mid] > k)
{
right = mid - 1; //去前半区间找
}
else if (arr[mid] < k)
{
left = mid + 1;
}
return FindFirstK(arr, k, left, right);
}
int FindLastK(int* arr, int k, int left, int right) //找最后一个k的位置
{
if (left > right) //闭区间
{
return -1;
}
int mid = left + ((right - left) >> 1);
if (arr[mid] == k)
{
if (((mid + 1 <= right) && (arr[mid + 1] != k)) || mid == right)
{
return mid; //此时为mid下标的即为最后一个k值
}
left = mid + 1; //二分法,去后半区间找
}
else if (arr[mid] > k)
{
right = mid - 1; //去前半区间找
}
else if (arr[mid] < k)
{
left = mid + 1;
}
return FindLastK(arr, k, left, right);
}
int GetNumOfK(int* arr, int length, int k)
{
if (arr == NULL || length <= 0)
{
return 0;
}
int left = 0;
int right = length - 1;
int FirstK = FindFirstK(arr, k, 0, length - 1);
int LastK = FindLastK(arr, k, 0, length - 1); //找最后一个k的位置
if ((FirstK <= LastK) && (FirstK >= 0) && (FirstK <= length) && (LastK >= 0) && (LastK <= length))
{
int count = LastK - FirstK + 1;
return count;
}
else
{
return 0;
}
}
void Test()
{
int arr[] = { 1, 2, 3, 3, 3, 3, 4, 5 };
int length = sizeof(arr) / sizeof(arr[0]);
int tty = GetNumOfK(arr, length, 3);
cout <<"出现的次数: "<<tty << endl;
}
int main()
{
Test();
system("pause");
return 0;
}