《剑指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)
总结:
第一,精确的能够抓住题目的特色,是排好序的数据,那么采用二分法查找可以将时间复杂度降低
第二,明确我们的目标。是统计个数,那么和原有的二分法区别是找到对应的下标即可。
出现新概念,我们要根据我们已经掌握的知识背景,找到与当前的问题联系,不可强求不可知,要从已知推未知。