题目:统计一个数字在排序数组中出现的次数。例如输入排序数组{1,2,3,3,3,3,4,5}和数字3,由于3在这个数组中出现了4次,因此输出4.
思路:排序的数组,最直接的想法就是二分查找。但是数字有重复,如果可以找到数字出现的起始位置和终止位置,那么就可以统计数字出现的次数,因此这个问题转化为用二分查找寻找数字出现的第一个位置和最后一个位置的问题。如果取数组的中位数,它等于要查找的数,那么在它之前可能还有等于它的数,如果它的前一个坐标的值也等于要查找的数,应该继续向前查找。同理对于寻找最后一个等于要查找的数,如果中位数的后一个数也等于要查找的数,则应继续向后查找,直到找到最后一个。
下面是用递归的方法实现的代码,循环的算法见我以前的博客:重新认识二分查找算法
int GetFirstK(int* data, int length, int k, int start, int end) { if(start > end) return -1; int mid = (start + end) / 2; if(data[mid] == k) { if(mid > 0 && data[mid-1] != k || mid == 0) return mid; else right = mid - 1; } else if(data[mid] < k) start = mid + 1; else end = mid - 1; return(data, length, k, start, end); } int GetLastK(int* data, int length, int k, int start, int end); { if(start > end) return -1; int mid = (start + end) / 2; if(data[mid] == k) { if(mid < length - 1 && data[mid+1] != k || mid == length - 1) return mid; else start = mid + 1; } else if(data[mid] < k) start = mid + 1; else end = mid - 1; return(data, length, k, start, end); } int GetNumberOfK(int* data, int length, int k) { int numbers = 0; if(data != NULL && length > 0) { int first = GetFirstK(data, length, k, 0, length - 1); int last = GetLastK(data, length, k, 0, length - 1); if(first > -1 && last > -1) numbers = last - first + 1; } return numbers; }