《剑指offer》数字在排序数组中出现的次数

本题来自《剑指offer》 数字在排序数组中出现的次数

题目:

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

思路:

   思路一:类似于查找,那么顺序遍历,当前值与目标值一直的时候,那么就统计,时间复杂度为O(n)。

   思路二:题目知,原始数据是排序的,那么可以采用二分查找法,类似于归并排序一样,时间复杂度为log(n)。首先找到目标值的第一个下标,其次找到最后一个下标,两者相见便是统计的个数。

C++ Code:log(n)

class Solution {
public:
    int GetNumberOfK(vector<int> data ,int k) {
        int number = 0;                                           //result initial value
        if (data.size()){                                         //boundary condition judgement
            int first = GetFirstK(data,k,0,data.size()-1);        //get the first of index about the target of k
            int last = GetLastK(data,k,0,data.size()-1);          //get the last of index about the target of k
            if (first>-1 && last>-1){                             //if the target appear in the data
                number = last-first+1;                            //then,the number is equal to the last position minus the first position
            }
        }
        return number;
    }
    int GetFirstK(vector<int> data,int k,int start,int end){     //the program of Get the index of first target
        if (start>end){                                          //if index of start large end ,then return -1
            return -1;
        }
        int middleIndex = (start + end)/2;                       //get index of middle
        int middleData = data[middleIndex];                      //get the value of middle in the data
        if (middleData == k){                                    //if the value of middle equal target k
            if ((middleIndex>0&&data[middleIndex-1]!=k)||middleIndex==0){
                return middleIndex;                              //only when meet the condition,return the first index
            }else{
                end = middleIndex-1;                             //then,the index of last is equal middle minus 1
            }
        }else if(middleData>k){                                  //the value of middle large target k
            end = middleIndex-1;                                 //target in the previous data,last index equal middle minus 1
        }else{                                                   //the value of middle small target k
            start = middleIndex+1;                               //target in the previous data,the first index equak middle plus 1
        }
        return GetFirstK(data,k,start,end);                      //recursive to get the first index of target k
    }
    int GetLastK(vector<int> data,int k,int start,int end){      //the program of get the index of last target
        if (start>end){                                          //smae as above
            return -1;
        }
        int middleIndex = (start+end)/2;                         //the index of middle
        int middleData = data[middleIndex];                      //the value of middle
        if (middleData==k){
            if((middleIndex<data.size()-1&&data[middleIndex+1]!=k)||middleIndex==data.size()-1){
                return middleIndex;
            }else{
                start = middleIndex + 1;
            }
        }else if(middleData<k){                                 //the target in the previous data
            start = middleIndex+1;
        }else{                                                  //the target in the last data
            end = middleIndex-1;
        }
        return GetLastK(data,k,start,end);
    }
}; 

Python Code:O(n)

总结:

  第一,精确的能够抓住题目的特色,是排好序的数据,那么采用二分法查找可以将时间复杂度降低

  第二,明确我们的目标。是统计个数,那么和原有的二分法区别是找到对应的下标即可。

  出现新概念,我们要根据我们已经掌握的知识背景,找到与当前的问题联系,不可强求不可知,要从已知推未知。

原文地址:https://www.cnblogs.com/missidiot/p/10783693.html