题目描述
统计一个数字在排序数组中出现的次数。
思路:
1)直接遍历整个数组,遇到该数字则加1,时间复杂度为 O ( n ) O(n) O(n);
2)利用二分搜索的思想。利用二分找到 k k k在排序数组中第一次出现的位置 f r s t k frstk frstk,再次利用二分找到 k k k在排序数组中最后一次出现的位置 l a s t k lastk lastk,则出现总次数为 l a s t k − f i r s t k + 1 lastk - firstk + 1 lastk−firstk+1,时间复杂度为 O ( l o g n ) O(log{n}) O(logn)
class Solution {
public:
int GetNumberOfK(vector<int> data ,int k) {
int number = 0;
int length = data.size();
if (!data.empty()) {
int first = GetFirstk(data, length, k, 0, length - 1);
int last = GetLastk(data, length, k, 0, length - 1);
if (first > -1 && last > -1)
number = last - first + 1;
}
return number;
}
int GetFirstk(vector<int> &data, int length, int k, int start, int end) {
if (start > end)
return -1;
int mi = (start + end)/2;
int md = data[mi];
if (md == k) {
//判断左边一位是否等于k,若不是则该k为第一个k
if ((mi > 0 && data[mi - 1] != k) || mi == 0)
return mi;
else
end = mi - 1;
}
else if (md < k)
start = mi + 1;
else
end = mi - 1;
return GetFirstk(data, length, k, start, end);
}
int GetLastk(vector<int> &data, int length, int k, int start, int end) {
if (start > end)
return -1;
int mi = (start + end)/2;
int md = data[mi];
if (md == k) {
//判断右边一位是否为k,若不是则为最后一位k
if ((mi < length - 1 && data[mi + 1] != k) || mi == length - 1)
return mi;
else
start = mi + 1;
}
else if (md < k)
start = mi + 1;
else
end = mi - 1;
return GetLastk(data, length, k, start, end);
}
};