统计一个数字在排序数组中出现的次数。
解题思路
二分法
有序数组中查找数字,很明显要我们使用二分法,找到目标数字后,可以向两边遍历统计目标数字出现的次数,但是如果目标数字出的次数很多,代码的效率会从O(logN)退化到O(N),所以这里我们可以直接两次二分法,分别找到目标数字区间的左边界left和有边界right,最后出现的次数就是right - left - 1次,这种方法只需要两次二分无需遍历即可得到结果,时间复杂度是O(logN)。
函数设计
如何用二分法查找目标数字区间的左/右边界呢?我们只需要让中间值在等于目标数字的时候继续向左/右移动指针即可,最后low指针一定会越过high指针,此时low指针指向的就是右边界,high指针指向的就是左边界。
代码
class Solution {
public int search(int[] nums, int target) {
if (nums.length == 0) return 0;
int low = 0;
int high = nums.length - 1;
int mid;
//先找右边界
while (low <= high) {
mid = (low + high) / 2;
if (nums[mid] <= target) {
low = mid + 1;
} else {
high = mid - 1;
}
}
int right = low;
//再找左边界
high = right - 1;
low = 0;
while (low <= high) {
mid = (low + high) / 2;
if (nums[mid] < target) {
low = mid + 1;
} else {
high = mid - 1;
}
}
int left = high;
return right - left - 1;
}
}