剑指offer系列之三十六:数字在排序数组中出现的次数

简介:

题目描述

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

因为是排序数组,自然联想到二分查找算法,这样我们在二分的时候可能会获取多个相同的数字。就是说,中间那个位置的值可能刚好是统计的那个值,假设为k。那么k还有可能在前面或者后面出现,在这个基础上继续二分当然也是可以的,如果能够在使用二分查找算法的时候统计出第一个k和最后一个k出现的位置,那么k出现的次数自然就确定了。第一个k出现的位置,可以使用二分查找算法,如果中间位置的值刚好是k,那么继续比较中间位置前面位置的值是不是也是k,如果不是那么该中间位置就是第一个k出现的位置,如果中间位置的前一个位置的值也是k,那么说明第一个k肯定出现在前半部分,继续二分即可。那么寻找最后一个k出现的位置也是一样的道理,比较中间位置后面一个位置的值是不是也是k,如果是说明最后一个k肯定出现在后半部分,继续二分即可,如果不是k的话,那么中间位置就是最后一个k出现的位置了,因为是排序数组,那么后面一个位置的值如果都不是k的话,其他位置更加不可能是k了。排序数组是一个关键

基于上述思路,实现的代码如下(已被牛客AC):

package com.rhwayfun.offer;

public class GetCountOfK {

    public int GetNumberOfK(int[] array, int k) {
        if (array == null || array.length <= 0)
            return 0;
        int count = 0;
        int firstIndexOfK = getFirstK(array, k, 0, array.length - 1);
        int lastIndexOfK = getLastK(array, k, 0, array.length - 1);
        if (firstIndexOfK >= 0 && lastIndexOfK >= 0)
            count = lastIndexOfK - firstIndexOfK + 1;
        return count;
    }

    private int getLastK(int[] array, int k, int start, int end) {
        if (start > end) return -1;
        int middleIndex = (start + end) / 2;
        int middleData = array[middleIndex];
        if (middleData == k) {
            if ((middleIndex < array.length - 1 && array[middleIndex + 1] != k)
                    || middleIndex == array.length - 1) {
                return middleIndex;
            } else {
                start = middleIndex + 1;
            }
        } else if (middleData > k) {
            end = middleIndex - 1;
        } else {
            start = middleIndex + 1;
        }
        return getLastK(array, k, start, end);
    }

    private int getFirstK(int[] array, int k, int start, int end) {
        if (start > end) return -1;
        int middleIndex = (start + end) / 2;
        int middleData = array[middleIndex];
        if (middleData == k) {
            if ((middleIndex > 0 && array[middleIndex - 1] != k)
                    || middleIndex == 0) {
                return middleIndex;
            } else {
                end = middleIndex - 1;
            }
        } else if (middleData > k) {
            end = middleIndex - 1;
        } else {
            start = middleIndex + 1;
        }
        return getFirstK(array, k, start, end);
    }

    public static void main(String[] args) {
        int[] array = new int[]{1,2,3,3,3,3,4,5};
        int count = new GetCountOfK().GetNumberOfK(array, 3);
        System.out.println(count);
    }
}
目录
相关文章
|
7月前
【错题集-编程题】数组中的最长连续子序列(排序 + 模拟)
【错题集-编程题】数组中的最长连续子序列(排序 + 模拟)
|
7月前
|
Java
每日一题《剑指offer》数组篇之数组中重复的数字
每日一题《剑指offer》数组篇之数组中重复的数字
59 0
每日一题《剑指offer》数组篇之数组中重复的数字
|
7月前
|
算法 Java
每日一题《剑指offer》数组篇之统计数字在排序数组中出现的次数
每日一题《剑指offer》数组篇之统计数字在排序数组中出现的次数
52 0
每日一题《剑指offer》数组篇之统计数字在排序数组中出现的次数
|
7月前
|
算法 Java
每日一题《剑指offer》数组篇之数组中出现次数超过一半的数字
每日一题《剑指offer》数组篇之数组中出现次数超过一半的数字
74 0
每日一题《剑指offer》数组篇之数组中出现次数超过一半的数字
【剑指offer】-数字在排序数组中出现的次数-32/67
【剑指offer】-数字在排序数组中出现的次数-32/67
【剑指offer】-1~n整数中1出现的次数-31/67
【剑指offer】-1~n整数中1出现的次数-31/67
|
C++
剑指offer 55. 数字在排序数组中出现的次数
剑指offer 55. 数字在排序数组中出现的次数
86 0
剑指offer 44. 从1到n整数中1出现的次数
剑指offer 44. 从1到n整数中1出现的次数
74 0
剑指offer_数组---数字在排序数组中出现的次数
剑指offer_数组---数字在排序数组中出现的次数
45 0
|
算法 C语言
剑指Offer 第53题:数字在升序数组中出现的次数
剑指Offer 第53题:数字在升序数组中出现的次数
143 0
剑指Offer 第53题:数字在升序数组中出现的次数