网站救助计划
1.为阅读体验,本站无任何广告,也无任何盈利方法,站长一直在用爱发电,现濒临倒闭,希望有能力的同学能帮忙分担服务器成本
2.捐助10元及以上同学,可添加站长微信lurenzhang888,备注捐助,网站倒闭后可联系站长领取本站pdf内容
3.若网站能存活下来,后续将会持续更新内容
题目描述
统计一个数字在排序数组中出现的次数。
示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: 2
示例 2:
输入: nums = [5,7,7,8,8,10], target = 6
输出: 0
提示:
- 0 <= nums.length <= 10^{5}
- -10^{9} <= nums[i] <= 10^{9}
- nums 是一个非递减数组
- -10^{9} <= target <= 10^{9}
题解
(二分) O(logn)
在排序数组中快速找一个数可以用二分,题目要求找出连续的一段数 target 的个数,可以做两次二分,二分左端点和二分右端点。
算法步骤:
- 二分左端点的条件:找到第一个大于等于 target 的数的位置 left
- 二分结束,如果左端点对应的值不是 target,说明 target 不存在,直接返回 0,否则继续二分右端点
- 二分右端点的条件:找到最后一个个小于等于 target 的数的位置 right
最后返回出现的次数 right – left + 1。
时间复杂度
二分的时间复杂度为 O(logn)
空间复杂度
O(1)
C++ 代码
class Solution {
public:
int search(vector<int>& nums, int target) {
if (nums.empty()) return 0;
int l = 0, r = nums.size() - 1;
while (l < r) {
int mid = l + r >> 1;
if (nums[mid] >= target) r = mid;
else l = mid + 1;
}
if (nums[l] != target) return 0;
int left = l;
l = 0, r = nums.size() - 1;
while (l < r) {
int mid = l + r + 1ll >> 1;
if (nums[mid] <= target) l = mid;
else r = mid - 1;
}
return r - left + 1;
}
};
Java 代码
class Solution {
public int search(int[] nums, int target) {
if (nums == null || nums.length == 0) {
return 0;
}
int l = 0, r = nums.length - 1;
while (l < r) {
int mid = l + (r - l) / 2;
if (nums[mid] >= target) {
r = mid;
} else {
l = mid + 1;
}
}
if (nums[l] != target) {
return 0;
}
int left = l;
l = 0;
r = nums.length - 1;
while (l < r) {
int mid = l + (r - l + 1) / 2;
if (nums[mid] <= target) {
l = mid;
} else {
r = mid - 1;
}
}
return r - left + 1;
}
}
Python 代码
class Solution:
def search(self, nums: List[int], target: int) -> int:
if not nums:
return 0
l, r = 0, len(nums) - 1
while l < r:
mid = l + (r - l) // 2
if nums[mid] >= target:
r = mid
else:
l = mid + 1
if nums[l] != target:
return 0
left = l
l, r = 0, len(nums) - 1
while l < r:
mid = l + (r - l + 1) // 2
if nums[mid] <= target:
l = mid
else:
r = mid - 1
return r - left + 1
本文由读者提供,Github地址:https://github.com/tonngw
点击面试手册,获取本站面试手册PDF完整版