题目描述
统计一个数字在排序数组中出现的次数。
解题思路
最简单的方法就是遍历一边数组,比较每一个数字,统计指定数字出现的次数。这样的解决办法时间复杂度为O(n),空间复杂度为O(1)。
代码实现
public class Solution {
public int GetNumberOfK(int [] array , int k) {
int count = 0;
for(int i = 0; i < array.length; i ++){
if(k == array[i]){
count ++;
}
}
return count;
}
}
优化方法
上面的方法虽然简单,但是不是最优的。既然是有序的数组,我们应该很容易想到二分查找的办法,通过二分查找找到该数字的起始地址以及结束地址,然后运算即可获取答案。
优化实现
public static int getNumberOfK(int[] array, int k) {
if (array == null || array.length == 0) {
return 0;
}
int startIndex = -1;
int endIndex = -1;
startIndex = getStartIndex(array, k, 0, array.length - 1);
endIndex = getEndIndex(array, k, 0, array.length - 1);
if (startIndex != -1 && endIndex != -1) {
return (endIndex - startIndex + 1);
}
return 0;
}
/**
* 用递归的方法查找首次出现k的位置
*
* @param array
* @param k
* @param start
* @param end
* @return
*/
public static int getStartIndex(int[] array, int k, int start, int end) {
if (start > end) {
return -1;
}
// 防止相加后溢出
int mid = start + ((end - start) >> 1);
if (array[mid] < k) {
return getStartIndex(array, k, mid + 1, end);
} else if (array[mid] > k) {
return getStartIndex(array, k, start, mid - 1);
} else if (mid - 1 >= 0 && array[mid - 1] == k) {
// 防止找到的不是第一个
return getStartIndex(array, k, start, mid - 1);
} else {
return mid;
}
}
/**
* 用循环的方法查找最后出现k的位置
*
* @param array
* @param k
* @param start
* @param end
* @return
*/
public static int getEndIndex(int[] array, int k, int start, int end) {
int length = array.length;
int mid = start + ((end - start) >> 1);
while (start <= end) {
if (array[mid] < k) {
start = mid + 1;
} else if (array[mid] > k) {
end = mid- 1;
} else if (mid + 1 < length && array[mid + 1] == k) {
// 防止找到的不是最后一个
start = mid + 1;
} else {
return mid;
}
mid = start + ((end - start) >> 1);
}
return -1;
}