题目描述
统计一个数字在排序数组中出现的次数。
牛客传送门:
点击打开链接
思路:
用二分来查找最左的位置与最右的位置,同时注意边界值。
测试用例:
[1,1,1,1,2,3,4],1 // 左边界
[1,2,3,3,3,3],3 // 右边界
[1,3,3,3,3,4,5],2 // 不在数组中
[1,2,3,3,3,3,4,5],3 // 正常用例
[1,2,3,3,3,3,4,5],3 // 正常用例
代码如下:
public class Title38 {
public int GetNumberOfK(int [] array , int k) {
if(array == null || array.length == 0 || array[0] > k ||
array[array.length-1] < k )
return 0;
int left = findLeft(array, 0, array.length-1, k);
// 如果数组中不存在k,返回0
if(left == -1)
return 0;
int right = findRight(array, 0, array.length-1, k);
return right - left + 1;
}
public int findLeft(int [] array,int begin,int end,int k){
int mid;
while(begin <= end){
mid = (begin + end) >>> 1;
if(array[mid] == k){
if(mid == 0 || array[mid-1] != k)
return mid;
end = mid-1;
}else if(array[mid] < k){
begin = mid+1;
}else if(array[mid] > k){
end = mid-1;
}
}
return -1;
}
public int findRight(int [] array,int begin,int end,int k){
int mid;
while(begin <= end){
mid = (begin + end) >>> 1;
if(array[mid] == k){
if(mid == array.length-1 || array[mid+1] != k)
return mid;
begin = mid+1;
}else if(array[mid] < k){
begin = mid+1;
}else if(array[mid] > k){
end = mid-1;
}
}
return 0;
}
public static void main(String[] args) {
Title38 clazz = new Title38();
// [1,3,3,3,3,4,5],2
// [1,2,3,3,3,3],3
// [1,1,1,1,2,3,4],1
int[] array = {1,2,3,3,3,3,4,5};
System.out.println(clazz.GetNumberOfK(array, 3));
}
}