统计一个数字在排序数组中出现的次数。
示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: 2
示例 2:
输入: nums = [5,7,7,8,8,10], target = 6
输出: 0
限制:
0 <= 数组长度 <= 50000
注意:本题与主站 34 题相同(仅返回值不同):https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/
解题思路
查找到target在nums出现的位置
假设存在边界为 left 和 right, 满足 nums[left] < target && nums[right] > target
我们要找到满足条件最大的left和最小的right
对应的窗口大小就是 right - left - 1;
具体实现:
用二分法,两次去查找左边和右边界
优化: 简化代码,其实可以都用左边界,而有边界求解改为 target+1的左边界求解, 对应窗口变为 right-left (无需1)
class Solution {
private:
// 找到>=target的左边界,就是满足 nums[i] >= target里的i的最小值
inline int BinaryLeft(vector<int>& nums, int target)
{
int l = 0;
int r = nums.size() -1 ;
int m = 0;
while (l <= r)
{
m = (l+r) >> 1;
if (nums[m] < target)
{
l = m + 1;
}
else//nums[m] >= target
{
r = m - 1;
}
}
// cout << target << " " << l << endl;
return l;
}
public:
int search(vector<int>& nums, int target) {
// 题目假设存在target,无法额外判断
// 二分查找都是left边界,等于是前开后闭,这里计算窗口无需额外减1
return BinaryLeft(nums, target+1) - BinaryLeft(nums, target);
}
};
代码实现的逻辑:
以nums = [5,7,7,8,8,10], target = 8为例:
1-、m=2,nums[m] < target,L=3;
2-、m=4;nums[4] >=8,R=3
最后返回L3,
以nums = [5,7,7,8,8,10], target = 9为例:
1-、m=2,nums[2] <9,L=3;
2-、m=4;nums[4] <9,L=5
3、m=5,nums[5]>=9,R=4
返回L5
最后得到值为:5-3=2