描述
给定一个长度为 n 的非降序数组和一个非负数整数 k ,要求统计 k 在数组中出现的次数
数据范围:0 < n < 1000 , 0 < k < 100,数组中每个元素的值满足 0 < val < 100
要求:空间复杂度 O(1),时间复杂度 O(logn)
示例1
输入:[1,2,3,3,3,3,4,5],3
复制返回值:4
示例2
输入:[1,3,4,5],6
复制返回值:0
想到了暴力解法和二分法,暴力解法时间复杂度为O(n)不符合要求,二分法为O(logn)符合要求,下面是二分法的js代码:
function GetNumberOfK(data, k){
if (data == null || data.length == 0) return 0;
// 只需要找出数组中第一个大于k和第一个等于k的数的下标,相减就可以获得k在数组中的长度
return UpperBound(data, k) - LowerBound(data, k);
}
function LowerBound(data, k){ // 找第一个大于等于k的下标
let l = 0, r = data.length, mid;
while (l < r ) {
mid = l + ((r - l) >> 1); // 这种写法可以避免整型相加时溢出,另>>1相当于/2取整
if (data[mid] >= k) r = mid;
else l = mid + 1;
}
return r;
}
function UpperBound(data, k){ // 找第一个大于k的下标
let l = 0, r = data.length, mid;
while (l < r ) {
mid = l + ((r - l) >> 1);
if (data[mid] > k) r = mid;
else l = mid + 1;
}
return r;
}
module.exports = {
GetNumberOfK : GetNumberOfK
};