题目:统计一个数字在排序数组中出现的次数。
思路:二分查找该数字第一次出现的位置,然后找最后一次出现的位置,相减即可。用二分查找,时间复杂度为O(log n)。
代码:
public int GetNumberOfK(int [] array , int k) {
if (array == null || array.length <= 0) {
return 0;
}
int start = GetFirstK(array, k, 0, array.length - 1);
if (start < 0) {
return 0;
}
System.out.println(start);
int end = GetLastK(array, k, start, array.length - 1);
System.out.println(end);
if (end < 0) {
return 0;
}
return end - start + 1;
}
private int GetFirstK(int [] array, int k, int start, int end) {
if (start > end) {
return -1;
}
int mid = (start + end) / 2;
int midData = array[mid];
if (midData == k) {
// 如果中间位置的前边不是k,或者此位置就是0,那么就是找到了,返回
if ((mid > 0 && array[mid - 1] != k) || mid == 0) {
return mid;
} else { // 否则,要找的位置在左边
end = mid - 1;
}
} else if (midData > k) { // 要找的位置在左边
end = mid - 1;
} else { // 要找的位置在右边
start = mid + 1;
}
return GetFirstK(array, k, start, end);
}
private int GetLastK(int [] array, int k, int start, int end) {
if (start > end) {
return -1;
}
int mid = (start + end) / 2;
int midData = array[mid];
if (midData == k) {
if ((mid < array.length - 1 && array[mid + 1] != k) || mid == array.length - 1) {
return mid;
} else {
start = mid + 1;
}
} else if (midData > k) {
end = mid - 1;
} else {
start = mid + 1;
}
return GetLastK(array, k, start, end);
}