统计一个数字在排序数组中出现的次数
代码
解法一
/** * 暴力求解,直接遍历 * @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); }