【面试题】统计一个有序数组中指定数字出现的次数


记录一个遇到过的面试题,比较文明。。在一个有序数组中统计一个指定数字出现的次数。

遍历一遍就行了,O(n),但是作为面试答案肯定有点简单的过分了;

于是有个稍微复杂点的思路,因为是有序数组,可以先二分查找到指定元素,然后再向两侧扩展就好了,这样二分查找的时间复杂度是O(logn),然后在加上k(被查找的字符串长度),当母字符串很长,而被查找字符串比较短的时候,这个耗时会比遍历有优势。具体代码实现如下:

public class Main {
    public static void main(String[] args) {
        int[] sortArr2 = new int[]{1, 2, 2, 2, 3, 3};
        num = 2;
        System.out.println(countNum(sortArr, num));
    }

    /**
     * 统计指定数字在有序数组中出现的次数
     * @param sortArr
     * @param num
     * @return
     */
    private static int countNum(int[] sortArr, int num) {
        if (sortArr.length == 0) {
            return 0;
        }
        int count = 0;
        //查找到num第一次出现的位置
        int pos = binarySearch(sortArr, 0, sortArr.length - 1, num);
        if (pos == -1) {
            return 0;
        }

        //向两侧顺序查找和num相等的数(因为数组是有序的)
        for (int i = pos; i > 0 && sortArr[i] == num; i --) {
            count ++;
            
        }
        for (int i = pos + 1; i < sortArr.length && sortArr[i] == num; i ++) {
            count ++;
        }
        return count;
    }

    /**
     * 二分查找
     * @param sortArr
     * @param start
     * @param end
     * @param num
     * @return
     */
    private static int binarySearch(int[] sortArr, int start, int end, int num) {
        if (start > end || (start == end && sortArr[start] != num)) {
            return -1;
        }
        int mid = (start + end) / 2;
        if (sortArr[mid] > num) {
            return findNum(sortArr, start, mid, num);
        } else if (sortArr[mid] < num) {
            return findNum(sortArr, mid + 1, end, num);
        } else {
            return mid;
        }
    }
}

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM