题目:统计一个数字在排序数组中出现的次数。
备注:思路一和思路二是一样的,思路二代码更加简洁。
常见的思路是利用二分查找到一个K之后向两边扫描,如果有N个K的话时间复杂度就是O(n),不如下面的思路时间复杂度低。
思路一:利用二分查找;查找第一个K的位置,查找最后一个K的位置,相减即可得到。时间复杂度为O(LogN)+O(LogN),所以总的时间复杂度为O(logN);
代码:
public class Solution {
public int GetNumberOfK(int [] array , int k) {
if(array==null||array.length==0)
return 0;
int num=0;
int first=getFirstOfK(array,k,0,array.length-1);
int last=getLastOfK(array,k,0,array.length-1);
if(first>-1&&last>-1) {
num = last - first + 1;
}
return num;
}
public int getFirstOfK(int [] array ,int k, int start,int end){
if(start>end)
return -1;
int mid=(start+end)/2;
if(array[mid]==k){
if(mid==0||(mid>0&&array[mid-1]!=k))
return mid;
else
end=mid-1;
}else if(array[mid]>k){
end=mid-1;
}else{
start=mid+1;
}
return getFirstOfK(array,k,start,end);
}
public int getLastOfK(int [] array , int k,int start,int end){
if(start>end)
return -1;
int mid=(start+end)/2;
if(array[mid]==k){
if(mid==array.length-1||(mid<array.length&&array[mid+1]!=k)){
return mid;
}else{
start=mid+1;
}
}else if(array[mid]<k){
start=mid+1;
}else{
end=mid-1;
}
return getLastOfK(array,k,start,end);
}
}
思路二:只写一个寻找第一个K节点的方法,可以找到第一个K和第一个K+1;
public int GetNumberOfK(int[] nums, int K) {
int first = binarySearch(nums, K);
int last = binarySearch(nums, K + 1);
return (first == nums.length || nums[first] != K) ? 0 : last - first;
}
private int binarySearch(int[] nums, int K) {
//这里使用h=nums.length,主要是考虑到最后一位也是K的情况
int l = 0, h = nums.length;
while (l < h) {
int m = l + (h - l) / 2;
if (nums[m] >= K)
h = m;
else
l = m + 1;
}
return l;
}