【剑指offer】面试题38:数字在排序数组中出现的次数
题目:
统计一个数字在排序数组中出现的次数。
思路:
对二分查找进行改进,找到数字在数组中第一次出现和最后一次出现的位置,这样就得到它出现的次数。
以找第一次出现的位置为例:如果mid元素大于k,则在前半段找;如果小于k,则在后半段找;如果等于k,则要看mid的前一个元素是不是k,如果是,则在前半段找,如果不是,则这就是第一次出现的位置。
时间复杂度O(logn)。
代码:
class Solution { public: int GetNumberOfK(vector<int> data ,int k) { if(data.size()<=0) return 0;//OMG!这里也是应该输出0 int first=GetFirstK(data,k,0,data.size()-1); int last=GetLastK(data,k,0,data.size()-1); if(first>=0 && last>=0) { return last-first+1; } return 0;//OMG!这里应该是0啊 } private: int GetFirstK(const vector<int> &data, int k, int begin, int end) { if(begin<0 || end>=data.size() || begin>end) return -1; int res=-1; int mid=begin+(end-begin)/2; if(data[mid]>k) res=GetFirstK(data,k,begin,mid-1); else if(data[mid]<k) res=GetFirstK(data,k,mid+1,end); else { if(mid==0 || (mid>0 && data[mid-1]!=k)) res=mid; else res=GetFirstK(data,k,begin,mid-1); } return res; } int GetLastK(const vector<int> &data, int k, int begin, int end) { if(begin<0 || end>=data.size() || begin>end) return -1; int res=-1; int mid=begin+(end-begin)/2; if(data[mid]>k) res=GetLastK(data,k,begin,mid-1); else if(data[mid]<k) res=GetLastK(data,k,mid+1,end); else { if(mid==data.size()-1 || (mid<data.size()-1 && data[mid+1]!=k)) res=mid; else res=GetLastK(data,k,mid+1,end); } return res;//!!!忘了这一句,找了好长时间错误!!! } };