题目描述
统计一个数字在排序数组中出现的次数。
思路一:暴力解法。
class Solution {
public:
int GetNumberOfK(vector<int> data ,int k) {
int len = data.size();
int count = 0;
for (int i = 0; i < len; i++)
{
if (data[i] == k)
count++;
}
return count;
}
};
思路二:一次二分查找。直接用二分查找法找到一个目标数字,然后在该位置前后两边顺序扫描,找出第一个和最后一个目标数字。
class Solution {
public:
int GetNumberOfK(vector<int> data ,int k) {
int len = data.size();
if (len == 0 || k < data[0] || k > data[len-1])
return 0;
int mid = biSearch(data,k);
if(mid < 0) //如果没有找到k,此时mid==-1,直接返回0
return 0;
int i = mid - 1,j = mid + 1;
int count = 1;
while(i >= 0 && data[i--] == k) //从mid向左边顺序查找并计数
count++;
while(j <= data.size() -1 && data[j++] == k)//从mid向右边查找并计数
count++;
return count;
}
int biSearch(vector<int> data,int k){
int begin = 0,end = data.size() - 1;
int mid;
while(begin <= end){
mid = (begin + end) >> 1;
if(data[mid] == k)
return mid;
else if(data[mid] < k)
begin = mid + 1;
else
end = mid - 1;
}
return -1;
}
};
思路三:两次二分查找。利用二分查找法分别找到第一个和最后一个目标数字。
class Solution {
public:
int GetNumberOfK(vector<int> data ,int k) {
int len = data.size();
if (len == 0 || k < data[0] || k > data[len-1])
return 0;
if(data.empty())
return 0;
//获得第一个出现的位置
int left = GetFirstK(data,k,0,data.size()-1);
//获得最后出现的位置
int right = GetLastK(data,k,0,data.size()-1);
int count = 0;
if(left != -1 && right != -1)
count = right - left + 1;
return count;
}
//用递归方式实现二分查找
int GetFirstK(vector<int> data,int k,int begin,int end){
if(begin > end)
return -1;
int mid = (begin+end) >> 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
begin = mid + 1;
return GetFirstK(data,k,begin,end);
}
//用循环方式实现二分查找
int GetLastK(vector<int> data,int k,int begin,int end){
int mid;
while(begin <= end){
mid = (begin + end) >> 1;
if(data[mid] > k)
end = mid - 1;
else if(data[mid] < k)
begin = mid + 1;
else if(mid < data.size() -1 && data[mid + 1] == k)
begin = mid + 1;
else
return mid;
}
return -1;
}
};
参考
https://blog.csdn.net/mbskypan/article/details/89495140