Java 实现数字在排序数组中出现的次数

统计一个数字在排序数组中出现的次数

代码

解法一

    /**
     * 暴力求解,直接遍历
     * @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);
    }

猜你喜欢

转载自blog.csdn.net/zl18310999566/article/details/80236273