剑指offer-----在排序数组中查找数字

1、题目描述

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

2、思路

方法一:

直接遍历整个数组,与该数字做比对,统计它出现的次数。时间复杂度O(n)。

方法二:

先用二分查找找到第一个k的下标,再用二分查找找到最后一个下标,最后一个k小标减去第一个k下标并加1,就是k在数组中出现的次数。时间复杂度为O(logn)。

利用二分查找找到第一个k的下标的过程:

拿中间的数字和k作比较,如果中间的是数字比k大,则在前一部分继续 查找第一个k;如果中间的数字比k小,则在后一部分继续查找第一个k;如果中间的数字等于k,则判断中间数字的前一个数字是否等于k,如果等于k,则继续在前一部分查找第一个k,否则,当前数字就是第一个k。

利用二分查找找到最后一个k的下标的过程与查找第一个k下标的过程类似。

3、代码

方法一代码实现:

public class Solution {
     public int GetNumberOfK( int [] array ,  int k) {
         int count= 0 ;
         for ( int i= 0 ;i<array.length;i++){
            if (array[i]==k)
                count++;
        }
         return count;
     }
}

方法二代码实现:

public class Solution {
    /**
    得到第一个k的索引
    */
    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){//如果中间值等于k
            if((middleIndex>0 && array[middleIndex-1]!=k) || middleIndex==0){//如果中间值的前一个数不为k或者中间值是第一个数
                return middleIndex;
            }else{//中间值的前一个数为k,则第一个k还在当前值的左边
                end = middleIndex - 1;
            }
        }else if(middleData > k){//中间值大于k,说明第一个k在中间值左边
            end = middleIndex - 1;
        }else{
            start = middleIndex + 1;//如果中间值小于k,说明第一个k在中间值右边
        }
        return GetFirstK(array,k,start,end);
    }
    /**
    得到最后一个k的索引
    */
    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){//判断中间值的后一个值是否为k
                return middleIndex;
            }else{
                start = middleIndex + 1;
            } 
        }else if(middleData < k){
            start = middleIndex + 1;
            
        }else{
            end = middleIndex - 1;
            
        }
        return GetLastK(array,k,start,end);
    }
    public int GetNumberOfK(int [] array , int k) {
        int number = 0;
        if(array.length > 0){//数组存在
            int first = GetFirstK(array,k,0,array.length-1);
            int last = GetLastK(array,k,0,array.length-1);
            if(first>-1 && last>-1){
                number = last - first + 1;
            }
        }
        return number;//返回数字在数组中出现的次数
       
    }
}

猜你喜欢

转载自blog.csdn.net/g1607058603/article/details/80878317