面试冲刺算法系列-21

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

看到升序,降序等代表有序的词就可以优先考虑二分法。
设定两个指针,分别指向第一个k和最后一个k,最后一个k减去第一个k的索引即可获得k的个数。

public class Solution {
    public int GetNumberOfK(int [] array , int k) {
       int length = array.length;
        int firstK = FindfirstK(array,k,0,length-1);//建立指向第一个k的指针
        int lastK = FindlastK(array,k,0,length-1);//建立指向第二个k的指针
        if(length == 0)
        {
            return 0;
        }
        if((firstK != -1)&&(lastK != -1))
        {
            return lastK-firstK+1;
        }
        return 0;
    }
        public int FindfirstK(int[] array,int k,int start,int end)//利用递归获取第一个k的值
        {
            if(start>end)
            {
                return -1;
            }
            int mid = (start+end)>>1;//>>1表示右移一位,二进制数中表示除以2
            if(array[mid]>k)//若array[mid]>k,表示k在mid的左侧
            {
                return FindfirstK(array,k,start,mid-1);//所以末尾指针指向mid-1,向左缩小查找范围
            }
            else if(array[mid]<k)
            {
                return FindfirstK(array,k,mid+1,end);//同上
            }
            else if((mid-1>=0)&&array[mid-1]==k)//若mid前一个值也是k,说明在mid之前就已经出现了k,所以需要向左一步步
                                                //跟进来获得第一个出现k的位置。
            {
                return FindfirstK(array,k,start,mid-1);
            }
            else
            {
                return mid;
            }
    }
    public int FindlastK(int[] array,int k,int start,int end)
    {
        int mid = (start+end)>>1;
        while(start<=end)
        {
            if(array[mid]<k)
            {
                start = mid+1;
            }
            else if(array[mid]>k)
            {
                end = mid-1;
            }
            else if((mid+1<=end)&&array[mid+1]==k)
            {
                start = mid+1;
            }
            else
            {
                return mid;
            }
            mid = (start+end)>>1;
            
        }
        return -1;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值