题目描述
统计一个数字在排序数组中出现的次数。
解题思路:
先通过二分查找找到该数字第一次出现的位置,再通过二分查找找到该数字最后一次出现的位置,最后返回两结果的差值即可。
注意二分搜索左值和右值在边界处理上不同,特别是搜索右边界时,必须是while(l+1 < r),否则就会陷入死循环,原因是mid的值由于取(l+r)/2整数,永远偏向左方,所以搜索到最后总会l与mid重合,r在另一边。正是由于这个条件,导致最后的元素没有能加入搜索区间,所以最后需要单独处理。
public class Solution {
public int GetNumberOfK(int [] array , int k) {
if(array.length < 1)
return 0;
int lower = getLower(array, k);
int upper = getUpper(array, k);
if(array[lower] == k && array[upper] == k)
return upper - lower + 1;
return 0;
}
private int getLower(int[] array, int k){
int l = 0;
int r = array.length-1;
while(l < r){
int mid = l + ((r-l) >>> 1);
if(array[mid] == k)
r = mid;
else if(array[mid] < k){
l = mid + 1;
}else
r = mid - 1;
}
return l;
}
private int getUpper(int[] array, int k){
int l = 0;
int r = array.length-1;
while(l+1 < r){
int mid = l + ((r-l) >>> 1);
if(array[mid] == k)
l = mid;
else if(array[mid] < k)
l = mid + 1;
else
r = mid - 1;
}
//单独处理最后一个元素
if(l < array.length-1 && array[l] == array[l+1])
l++;
return l;
}
}