1. 程式人生 > >Java 實現數字在排序陣列中出現的次數

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);
    }