題目:
統計一個數字在排序數組中出現的次數。
思路:
1、順序遍歷
順序掃描一遍數組,統計該數字出現的次數。
時間復雜度:O(n)
2、二分查找
假設我們需要找的數字是k,那么就需要找到數組中的第一個k和最后一個k出現的位置。
如何通過二分查找得到第一個k的位置呢?
取數組中間的數字與k作比較,
如果該數字比k大,那么k只能出現在前半部分,那么下一輪只能在前半部分找;
如果該數字比k小,那么k只能出現在后半部分,那么下一輪只能在后半部分找;
如果該數字等於k,需要判斷這是不是第一個k,如果該數字的前一個數字不是k,那么該數字就是第一個k,否則需要在前半部分繼續尋找第一個k;
尋找最后一個k的方法與尋找第一個k的方法一樣。
代碼:
#include <iostream>
using namespace std;
int getFirstK(int* data,int k,int start,int end){
while(start<=end){
int mid=start+((end-start)>>1);
if(data[mid]==k){
if((mid>0 && data[mid-1]!=k) || mid==0)
return mid;
else
end=mid-1;
}
else if(data[mid]>k)
end=mid-1;
else
start=mid+1;
}
return -1;
}
int getLastK(int* data,int length,int k,int start,int end){
while(start<=end){
int mid=start+((end-start)>>1);
if(data[mid]==k){
if((mid<length-1 && data[mid+1]!=k) || mid==length-1)
return mid;
else
start=mid+1;
}
else if(data[mid]<k)
start=mid+1;
else
end=mid-1;
}
return -1;
}
int getNumberOfK(int* data,int length,int k){
if(data==NULL || length<=0)
return 0;
int first=getFirstK(data,k,0,length-1);
int last=getLastK(data,length,k,0,length-1);
cout<<first<<" "<<last<<endl;
if(first!=-1 && last!=-1)
return last-first+1;
return 0;
}
int main()
{
int A[]={1,2,3,3,3,3,4,5};
int len=sizeof(A)/sizeof(A[0]);
int k=3;
cout << getNumberOfK(A,len,k) << endl;
return 0;
}
在線測試OJ:
http://www.nowcoder.com/books/coding-interviews/70610bf967994b22bb1c26f9ae901fa2?rp=2
AC代碼:
class Solution {
public:
int GetNumberOfK(vector<int> data,int k) {
int len=data.size();
if(len<=0)
return 0;
int first=getFirstK(data,k,0,len-1);
int last=getLastK(data,len,k,0,len-1);
if(first!=-1 && last!=-1)
return last-first+1;
return 0;
}
int getFirstK(const vector<int> &data,int k,int start,int end){
int mid;
while(start<=end){
mid=start+((end-start)>>1);
if(data[mid]==k){
if((mid>0 && data[mid-1]!=k) || mid==0)
return mid;
else
end=mid-1;
}
else if(data[mid]>k)
end=mid-1;
else
start=mid+1;
}
return -1;
}
int getLastK(const vector<int> &data,int length,int k,int start,int end){
int mid;
while(start<=end){
mid=start+((end-start)>>1);
if(data[mid]==k){
if((mid<length-1 && data[mid+1]!=k) || mid==length-1)
return mid;
else
start=mid+1;
}
else if(data[mid]>k)
end=mid-1;
else
start=mid+1;
}
return -1;
}
};
