剑指offer37_数字在升序数组中出现的次数_题解
数字在升序数组中出现的次数
题目描述
统计一个数字在升序数组中出现的次数。
分析
方案一:二分查找(STL)
lower_bound(begin, end, target):查找第一个大于或等于target的元素
upper_bound(begin, end, target):查找第一个大于target的元素
数字target出现的次数
=target最后一次出现的数字下标-target第一次出现的数字下标+1
=第一个大于target的元素的下标-第一个等于target的元素下标
代码
/**
1.时间复杂度:O(logn)
二分法为对数级别复杂度。
2.空间复杂度:O(1)
几个变量使用常数大小的额外空间。
**/
class Solution
{
public:
int GetNumberOfK(vector<int> data, int k)
{
return upper_bound(data.begin(), data.end(), k) - lower_bound(data.begin(), data.end(), k);
}
};
方案二:二分查找(手动)
二分上下界为左闭右闭的[left, right],传入的初值为[0, n]
代码
class Solution
{
public:
int GetNumberOfK(vector<int> data, int k)
{
//特判
if(data.empty())
return 0;
int lbound = 0, ubound = 0;
//左闭右闭区间[0,n-1]
int l = 0, r = data.size() - 1;
//寻找第一个大于等于k的元素
while (l < r)
{
int mid = l + (r - l) / 2;
if (data[mid] >= k)
{
r = mid;
}
else
{
l = mid + 1;
}
}
if(data[l] < k)
l++;
lbound = l;
l = 0, r = data.size() - 1;
//寻找第一个大于k的元素
while (l < r)
{
int mid = l + (r - l) / 2;
if (data[mid] > k)
{
r = mid;
}
else
{
l = mid + 1;
}
}
if(data[l] <= k)
l++;
ubound = l;
return ubound - lbound;
}
};