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

题目:统计一个数字在排序数组中出现的次数。例如输入排序数组{1,2,3,3,3,3,4,5}和数字3,由于3在这个数组中出现了4次,因此输出4。

暴力解法的时间复杂度为O(n),还有更优的解法,运用二分查找,时间复杂度为O(logn):

1.先找出第一次出现的下标值,设left,mid,right分别代表数组的起始,中间,结束的下标。

若数组中间的数a[mid]大于k,则right = mid -1;

若数组中间的数a[mid]小于k,则left = mid+1;

若数组中间的数a[mid]等于k,判断a[mid-1] 是否等于k,若不等于,说明是第一次出现的下标,返回mid下标;若等于,则说明第一次出现的下标还在mid的左边,right = mid -1;

递归重复以上过程。

2.再找出最后出现的下标,原理同上。

参考代码:

package test;

import org.junit.Test;

public class Solution {
    public int getNumOfK(int[] a, int k) {
        if (a == null || a.length == 0)
            return 0;
        int first = getFirstK(a, 0, a.length - 1, k);
        int last = getLastK(a, 0, a.length - 1, k);
        if (first > -1 && last > -1)
            return last - first + 1;
        return 0;
    }

    private int getFirstK(int[] a, int left, int right, int k) {
        if (left > right)
            return -1;
        int mid = (left + right) / 2;
        int midData = a[mid];
        // 中间的数等于k
        if (midData == k) {
            //mid的前一个数不是k,说明是第一个出现的数
            if (mid > 0 && a[mid - 1] != k || mid == 0)
                return mid;
            else
                //不是第一个出现的数,第一个出现的数再数组的左边
                right = mid - 1;
            // 中间的数大于k,说明在数组的左边
        } else if (midData > k)
            right = mid - 1;
        else
            // 中间的数小于k,说明在数组的右边
            left = mid + 1;
        return getFirstK(a, left, right, k);
    }

    private int getLastK(int[] a, int left, int right, int k) {
        if (left > right)
            return -1;
        int mid = (left + right) / 2;
        int midData = a[mid];
        if (midData == k) {
            if (mid < a.length - 1 && a[mid + 1] != k || mid == a.length - 1)
                return mid;
            else
                left = mid + 1;
        } else if (midData > k)
            right = mid - 1;
        else
            left = mid + 1;
        return getLastK(a, left, right, k);
    }

    @Test
    public void testSolution() {
        int[] a = { 1, 2, 3, 3, 3, 3, 4, 5 };
        int k = 3;
        System.out.println(getNumOfK(a, k));//4
    }
}
原文地址:https://www.cnblogs.com/tongkey/p/7816778.html