【剑指offer】53-1、数字在排序数组中出现的次数

博客围绕统计排序数组中数字出现次数展开。先给出题目示例,接着阐述解题思路,利用二分查找算法找第一个目标数字,根据中间数字与目标数字大小关系及相邻数字情况确定查找范围。还列举了功能、边界值和特殊测试用例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

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

解题思路

        首先分析如何用二分查找算法在数组中找到第一个k。二分查找算法总是先拿数组中间的数字和k作比较。如果中间的数字比k大,那么k只有可能出现在数组的前半段,下一轮我们只在数组的前半段查找就可以了。如果中间的数字比k小,那么k只有可能出现在数组的后半段,下一轮我们只在数组的后半段查找就可以了。

        如果中间的数字和k相等呢?我们先判断这个数字是不是第一个k。

        如果位于中间数字的前面一个数字不是k,此时中间的数字刚好就是第一个k。

        如果中间数字的前面一个数字也是k,也就是说第一个k肯定在数组的前半段,下一轮我们仍然需要在数组的前半段查找

测试用例

       1.功能测试(数字出现次数为0、1、2等)

  2.边界值测试(数组只有一个数字,查找数字为第一个或者最后一个)

  2.特殊测试(null)

代码

package mySword;

//题目:统计一个数字在排序数组中出现的次数。
//例如输入排序数组{1, 2, 3, 3, 3, 3, 4, 5}和数字3,由于3在这个数组中出现了4次,因此输出4。
public class getNumberOfK {
    public static int getNumberOfK(int[] arr, int k){
        if(arr == null || arr.length == 0){
            return -1;
        }
        int indexOfFirstK = getFirstK(arr, 0 , arr.length-1, k);
        int indexOfLastK = getLastK(arr, 0, arr.length-1, k);

        return indexOfLastK - indexOfFirstK + 1;
    }

    //GetFirstK:找到数组中第一个k的下标。如果数组中不存在k,返回-1
    public static int getFirstK(int[] arr, int start, int end, int k){
        if(start > end){
            return -1;
        }

        int mid = start + (end - start)/2;
        if(arr[mid] == k){
            if(mid == 0 || arr[mid-1] != k){
                return mid;
            }else{
                end = mid - 1;
            }
        }else if(arr[mid] < k){
            start = mid+1;
        }else{
            end = mid-1;
        }
        return getFirstK(arr, start, end, k);
    }

    //GetLastK:找到数组中最后一个k的下标。如果数组中不存在k,返回-1
    public  static int getLastK(int[] arr, int start, int end, int k){
        while(start > end){
            return -1;
        }

        int mid = start + (end - start)/2;
        if(arr[mid] == k){
            if(mid == arr.length-1 || arr[mid+1] != k){
                return mid;
            }else{
                start = mid + 1;
            }
        }else if(arr[mid] < k){
            start = mid + 1;
        }else{
            end = mid - 1;
        }
        return getLastK(arr, start, end, k);
    }

    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 3, 3, 3, 4, 5};
        System.out.println(getNumberOfK(arr, 3));
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值