统计一个数字在排序数组中出现的次数。
思路一
遍历数组 o(n)
遍历数组
int count = 0;
for(int i = 0 ; i < array.length; i++){
if(array[i] == k){
count ++;
}
}
return count;
思路二
既然提到有序数组那必然想到二分查找
二分查找
图片来自于百度
二分查找算法思想
有序的序列,每次都是以序列的中间位置的数来与待查找的关键字进行比较,每次缩小一半的查找范围,直到匹配成功。
二分查找优缺点
优点是比较次数少,查找速度快,平均性能好;
其缺点是要求待查表为有序表,且插入删除困难。
因此,折半查找方法适用于不经常变动而查找频繁的有序列表。
使用条件:
查找序列是顺序结构,有序。
在网友的博客中有详细的java代码实现,
https://blog.youkuaiyun.com/maoyuanming0806/article/details/78176957
在思路二中, 需要使用两次二分查找
第一次找出第一个k的位置 第二次找最后一个k的位置
然后用lastk - firstk +1 得出k出现的个数
public class Solution {
public int GetNumberOfK(int [] array , int k) {
/*遍历数组
int count = 0;
for(int i = 0 ; i < array.length; i++){
if(array[i] == k){
count ++;
}
}
return count;
*/
//思路二遍历数组
int length = array.length;
if(length == 0 ){
return 0;
}
int result = 0;
int firstK = getFirstK(array,k,0,length-1);
int lastK = getLastK(array,k,0,length-1);
if(firstK > -1 && lastK > -1){
result = lastK - firstK+1;
}
return result;
}
//递归写法
private int getFirstK(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 && array[mid - 1] != k)
|| mid == 0)
return mid;
else
end = mid - 1;
}
else if(array[mid] > 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;
if(array[mid] == k){
if((mid < array.length -1 && array[mid + 1] != k)|| mid == array.length -1)
return mid;
else
start = mid +1;
}
else if(array[mid] < k){
start = mid+1;
}
else {
end = mid-1;
}
return getLastK(array, k, start, end);
}
}