数字在排数组中的出现次数
补充:默认升序数组。
思路:
升序,就先想到二分法,找到第一个k的索引,最后一个k的索引,last-first+1
1、查第一个k
if[mid] > k:
说明第一个k出现在左边的子数组,因此 end = mid-1;
if [mid] < k:
说明第一个k出现在右边的数组,因此 start = mid+1;
if [mid] == k:
得看mid之前还有没有k了,如果有,说明k还在左边数组,如果没有了,说明这个[mid]就正好是第一个k;
看mid之前,得保证mid之前确实还有元素,比如说mid=0,那么mid之前就没有元素了,那么[mid]就是第一个k,即数组第一个元素就是k
2、查找最后一个k
同理,不再描述
测试:
数组中包含k,数组中没有k,查找的k只出现一次
边界情况:
k是数组最小值;
k是最大值;
数组只有一个数字。
代码
1 class Solution { 2 public: 3 int GetNumberOfK(vector<int> data ,int k) { 4 if(data.empty()) return 0; 5 int num = 0; 6 int first=getfirstk(data,0,data.size()-1,k); 7 int last = getlastk(data,0,data.size()-1,k); 8 if(first>-1 && last>-1) num=last-first+1; 9 return num; 10 } 11 int getfirstk(vector<int> vec,int start,int end,int k){ 12 if(start>end) return -1;//-1是因为如果第一个k在0索引的情况 13 int mid=start+(end-start)/2;//不用(start+end)/2是害怕start+end时内存溢出 14 int hehe = vec[mid]; 15 if(hehe==k){ 16 if((mid>start && vec[mid-1]!=k) || mid==start) return mid; 17 else end=mid-1; 18 } 19 else if(hehe>k) end=mid-1; 20 else start=mid+1; 21 return getfirstk(vec,start,end,k); 22 } 23 int getlastk(vector<int> vec,int start,int end,int k){ 24 if(start>end) return -1; 25 int mid=start+(end-start)/2; 26 int hehe = vec[mid]; 27 if(hehe==k){ 28 if((mid<end && vec[mid+1]!=k) || mid==end) return mid; 29 else start = mid+1; 30 } 31 else if(hehe>k) end=mid-1; 32 else start=mid+1; 33 return getlastk(vec,start,end,k); 34 } 35 };