问题重述:
题目:统计一个数字在排序数组中出现的次数。例如输入排序数组{1,2,3,3,3,3,4,5}和3,由于3在数组中出现了4次,因此输入4。
思路接下:
大家的首先反应可能是用二分法先找到一个数字,假设为k,然后在从此位置处向前和向后搜索k,此方法的时间复杂度其实还是O(n),显然是不萌满足要求的。
因此我们可以用二分法找到一个k和最后一个k,即得到了所有k的数量。
找到第一个k的思路如下:
首先用二分法找到k,然后判断mid-1处是不是k,如果不是,那么mid就是k第一次出现的位置,如果mid-1处还是k,那么我们用二分法继续向前查找。找最后一个k的思路是相同的。
代码实现:
在实现代码的时候,我们要注意一些边缘的条件,我自己在这里吃了不少的亏。
class Solution {
public:
int getLastK(vector<int> data, int k)
{
int start = 0;
int end = data.size()-1;
while (start <= end)
{
int mid = (start + end) / 2;
if (data[mid] < k)
{
start = mid + 1;
continue;
}
if (data[mid] > k)
{
end = mid - 1;
continue;
}
if (data[mid == k])
{
if(mid == data.size()-1&&data[mid]==k)
return mid;
if (mid + 1 < data.size() && data[mid + 1] != k)
return mid;
else
start = mid + 1;
}
}
return -1;
}
int getFirstK(vector<int> data, int k)
{
int start = 0;
int end = data.size()-1;
while (start <= end)
{
int mid = (start + end) / 2;
if (data[mid] < k)
{
start = mid + 1;
continue;
}
if (data[mid] > k)
{
end = mid - 1;
continue;
}
if (data[mid == k])
{
if(mid==0&&data[mid]==k)
return mid;
if (mid - 1 >= 0 && data[mid - 1] != k)
return mid;
else
end = mid - 1;
}
}
return -1;
}
int GetNumberOfK(vector<int> data, int k) {
int first = getFirstK(data, k);
int last = getLastK(data, k);
if(last==-1||first==-1)
return 0;
return last - first +1;
}
};