统计一个数字在排序数组中出现的次数
代码
解法一
/**
* 暴力求解,直接遍历
* @param array
* @param k
* @return
*/
public static int findAppearCountInArrayOfK(int[] array, int k) {
if (array == null || array.length == 0) {
return 0;
}
int count = 0;
for (int i = 0; i < array.length; i++) {
if (array[i] == k) {
count++;
}
}
return count;
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 3, 3, 3};
int c = findAppearCountInArrayOfK(array, 3);
System.out.print(c);
}
解法二
/**
* 基于二分查找,分别查找开始和结束位置,求差
* @param array
* @param k
* @return
*/
public static int findAppearCountInArrayOfK2(int[] array, int k) {
if (array == null || array.length == 0) {
return 0;
}
int first = findFirstIndexOfK(array, k);
int last = findLastIndexOfK(array, k);
if (first > -1 && last > -1) {
System.out.println(first + " - " + last);
return last - first + 1;
}
return 0;
}
/**
* 求k的开始位置
* @param array
* @param k
* @return
*/
private static int findFirstIndexOfK(int[] array, int k) {
int low = 0;
int high = array.length - 1;
int middle = 0;
int middleData = 0;
while (low <= high) {
// 计算中点
middle = (low + high) / 2;
// 得到中位数
middleData = array[middle];
if (middleData == k) {
// 如果中位数等于目标值
// 此时如果中点恰恰是数组的起始位置,说明前面没有元素,则直接返回该位置
// 如果前面还有元素,并且不等于目标值,说明当前位置就是目标值的开始位置,直接返回
// 都不满足,说明没有找到,则修改数组搜索范围的high,以当前数组的中点为界,二分查找左侧子数组
if (middle == 0 || array[middle - 1] != k) {
return middle;
} else {
high = middle - 1;
}
} else if (middleData > k) {
// 如果中位数大于k,说明k在左侧子数组中,继续下一次二分查找
high = middle - 1;
} else {
// 如果中位数小于k,说明k在右侧子数组中,继续下一次二分查找
low = middle + 1;
}
}
return -1;
}
private static int findLastIndexOfK(int[] array, int k) {
int low = 0;
int high = array.length - 1;
int middle = 0;
int middleData = 0;
while (low <= high) {
middle = (low + high) / 2;
middleData = array[middle];
if (middleData == k) {
// 如果中位数等于目标值
// 此时如果中点恰恰是数组的结束位置,说明后面没有元素,则直接返回该位置
// 如果后面还有元素,并且不等于目标值,说明当前位置就是目标值的结束位置,直接返回
// 都不满足,说明没有找到,则修改数组搜索范围的low,以当前数组的中点为界,二分查找右侧子数组
if (middle == array.length - 1 || array[middle + 1] != k) {
return middle;
} else {
low = middle + 1;
}
} else if (middleData > k) {
// 如果中位数大于k,说明k在左侧子数组中,继续下一次二分查找
high = middle - 1;
} else {
// 如果中位数小于k,说明k在右侧子数组中,继续下一次二分查找
low = middle + 1;
}
}
return -1;
}
public static void main(String[] args) {
int[] array = {1, 2, 3, 3, 3, 3};
int c = findAppearCountInArrayOfK2(array, 3);
System.out.print(c);
}