给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。
#include <vector>
using namespace std;
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
vector<int> result = {-1, -1};
int left = binarySearchLeft(nums, target);
if (left == -1) {
return result;
}
int right = binarySearchRight(nums, target);
result[0] = left;
result[1] = right;
return result;
}
private:
int binarySearchLeft(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
if (left < nums.size() && nums[left] == target) {
return left;
}
return -1;
}
int binarySearchRight(vector<int>& nums, int target) {
int left = 0, right = nums.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] <= target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
if (right >= 0 && nums[right] == target) {
return right;
}
return -1;
}
};
时间复杂度分析:
二分查找起始位置:binarySearchLeft函数的时间复杂度为 O(log n),因为它是通过二分查找来定位目标值的起始位置的。
二分查找结束位置:binarySearchRight函数的时间复杂度也为 O(log n),同样是通过二分查找来定位目标值的结束位置的。
总体时间复杂度:由于我们分别调用了两次 O(log n) 的二分查找函数,因此整体的时间复杂度为 O(log n)。
空间复杂度分析:
算法本身没有使用额外的数据结构或递归调用,只使用了常数级别的额外空间来存储一些变量和返回结果。
因此,空间复杂度为 O(1)。
综上所述,该算法的时间复杂度为 O(log n),空间复杂度为 O(1)。