题目描述
统计一个数字在排序数组中出现的次数。
二分查找:递归写法
/*递归写法*/
class Solution {
/*二分查找 找到第一个K 和 最后一个K 二者位置相减*/
public:
int GetNumberOfK(vector<int> data ,int k)
{
if(data.empty())
return 0;
int number = 0;
int first = GetFirstIndex(data,k,0,data.size()-1);
int last = GetLastIndex(data,k,0,data.size()-1);
if(first>-1 && last>-1)
number = last - first +1;
return number;
}
int GetFirstIndex(vector<int> &data,int k,int start,int end)
{
if(start > end)
return -1;
int mid = start+(end-start)/2;
if(data[mid] == k)
{
if((mid == start) || (data[mid-1] != k))
return mid;
else
end = mid-1;
}
else if(data[mid] > k)
end = mid - 1;
else
start = mid + 1;
return GetFirstIndex(data,k,start,end);
}
int GetLastIndex(vector<int> &data,int k,int start,int end)
{
if(start > end)
return -1;
int mid = start+(end-start)/2;
if(data[mid]==k)
{
if((mid == end) || (data[mid+1] != k))
return mid;
else
start = mid +1;
}
else if(data[mid]>k)
end = mid-1;
else
start = mid+1;
return GetLastIndex(data,k,start,end);
}
};
二分查找:循环写法
/*循环写法*/
class Solution
{
/*二分查找 找到第一个K 和 最后一个K 二者位置相减*/
public:
int GetNumberOfK(vector<int> data ,int k)
{
if(data.empty())
return 0;
int number = 0;
int first = GetFirstIndex(data,k,0,data.size()-1);
int last = GetLastIndex(data,k,0,data.size()-1);
if(first>-1 && last>-1)
number = last - first +1;
return number;
}
int GetFirstIndex(vector<int> &data,int k,int start,int end)
{
if(start > end)
return -1;
while(start <= end)
{
int mid = (start + end)/2;
if(data[mid] < k)
start = mid + 1;
else
end = mid - 1;
}
return start;
}
int GetLastIndex(vector<int> &data,int k,int start,int end)
{
if(start > end)
return -1;
while(start <= end)
{
int mid = (start + end)/2;
if(data[mid] <= k)
start = mid + 1;
else
end = mid - 1;
}
return end;
}
};
二分法:另一种思路,由于容器中都是整数,不是搜索k的两个位置,而是搜索k-0.5和k+0.5这两个数应该插入的位置,然后相减即可得出k的个数。
class Solution
{
public:
int GetNumberOfK(vector<int> data ,int k)
{
return biSearch(data, k+0.5) - biSearch(data, k-0.5) ;
}
private:
int biSearch(const vector<int> & data, double num)
{
int start = 0, end = data.size()-1;
while(start <= end)
{
int mid = (end - start)/2 + start;
if(data[mid] < num)
start = mid + 1;
else if(data[mid] > num)
end = mid - 1;
}
return start;
}
};