题目描述
统计一个数字在升序数组中出现的次数。
牛客链接:
https://www.nowcoder.com/practice/70610bf967994b22bb1c26f9ae901fa2?tpId=13&&tqId=11190&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking
解题思路:
有三种方法:
第一种是暴力解决,遍历得到k的次数
第二种由于数组升序,使用二分查找定位k出现的第一个位置和最后一个位置
第三种因为data中都是整数,所以可以稍微变一下,不是搜索k的两个位置,而是搜索k-0.5和k+0.5。这两个数应该插入的位置,然后相减即可。
代码一:
暴力解决,其时间复杂度为o(n)
class Solution {
public:
int GetNumberOfK(vector<int> data ,int k) {
int low = 0;
int high = data.size()-1;
if(data.size()==0)return 0;
int count = 0;
while(data[low] != k && low <= data.size()-1) {
low++;
}
while(data[low] == k && low <= data.size()-1) {
low++;
count++;
}
return count;
}
};
代码二:
使用二分查找定位k出现的第一个位置和最后一个位置,时间复杂度o(logN)
class Solution {
public:
int GetNumberOfK(vector<int> data ,int k) {
if(data.size() == 0) return 0;
int first = getFirstK(data, k, 0, data.size()-1);
int last = getLastK(data, k, 0, data.size()-1);
int count = 0;
if (first != -1 && last != -1) {
count = last - first + 1;
}
return count;
}
int getFirstK(vector<int> data, int k, int begin, int end) {
if (begin > end)
return -1;
int mid = (begin + end)/2;
if (data[mid] == k) {
if ((mid>0 && data[mid-1] != k) || (mid == 0)) {
return mid;
} else {
return getFirstK(data, k, begin, mid-1);
}
} else if (data[mid] > k) {
return getFirstK(data, k, begin, mid-1);
} else {
return getFirstK(data, k, mid+1, end);
}
}
int getLastK(vector<int> data, int k, int begin, int end) {
if (begin > end)
return -1;
int mid = (begin + end)/2;
if (data[mid] == k) {
if ((mid<data.size()-1 && data[mid+1] != k) || (mid == data.size()-1)) {
return mid;
} else {
return getLastK(data, k, mid+1, end);
}
} else if (data[mid] > k) {
return getLastK(data, k, begin, mid-1);
} else {
return getLastK(data, k, mid+1, end);
}
}
};
代码三:
因为data中都是整数,所以可以稍微变一下,不是搜索k的两个位置,而是搜索k-0.5和k+0.5。这两个数应该插入的位置,然后相减即可。时间复杂度o(logN)。
class Solution {
public:
int GetNumberOfK(vector<int> data ,int k) {
int count = 0;
if (data.size() == 0) {
return count;
}
count = biSearch(data, k+0.5) - biSearch(data, k-0.5);
return count;
}
int biSearch(vector<int> data, double num) {
int begin = 0;
int end = data.size()-1;
while (begin <= end) {
int mid = (end-begin)/2 + begin;
if(data[mid] > num) {
end = mid-1;
}else {
begin = mid + 1;
}
}
return begin;
}
};
注意:
二分查找
数字比较规律