34. 在排序数组中查找元素的第一个和最后一个位置
给你一个按照非递减顺序排列的整数数组 nums,和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
你必须设计并实现时间复杂度为 O(log n) 的算法解决此问题。
方法二:两次二分
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
if (nums.size() < 1) return { -1,-1 };
vector<int> ans;
int left = 0, right = nums.size() - 1;
int mid = (left + right) / 2;
// 先找最左侧的那个元素
while (right - left > 1) {
cout << left << " " << mid << " " << right << endl;
if (nums[left] <= target && nums[mid] >= target) {
right = mid;
}
else if (nums[right] >= target && nums[mid+1] <= target) {
left = mid+1;
}
else {
break;
}
mid = (left + right) / 2;
}
if (nums[left] == target) {
ans.push_back(left);
}
else if (nums[right] == target) {
ans.push_back(right);
}
else {
ans.push_back(-1);
}
left = 0, right = nums.size() - 1;
mid = (left + right) / 2;
// 先找最右侧的那个元素
while (right - left > 1) {
cout << left << " " << mid << " " << right << endl;
if (nums[right] >= target && nums[mid] <= target) {
left = mid ;
}else if (nums[left] <= target && nums[mid] >= target) {
right = mid;
}
else {
break;
}
mid = (left + right) / 2;
}
if (nums[right] == target) {
ans.push_back(right);
}
else if (nums[left] == target) {
ans.push_back(left);
}
else {
ans.push_back(-1);
}
return ans;
}
};
方法一:迭代
class Solution {
public:
vector<int> ans = {-1, -1};
int time = 0;
void searchMid(vector<int>& nums, int target, int start_idx, int end_idx) {
if (end_idx - start_idx >= 1) {
int mid = (start_idx + end_idx) / 2;
if (nums[start_idx] <= target && nums[mid] >= target) {
searchMid(nums, target, start_idx, mid);
}
if (nums[mid + 1] <= target && nums[end_idx] >= target) {
searchMid(nums, target, mid + 1, end_idx);
}
return;
} else {
if (nums[start_idx] == target) {
if (ans[0] == -1 || ans[0] > start_idx) {
ans[0] = start_idx;
}
if (ans[1] == -1) {
ans[1] = start_idx;
}
}
if (nums[end_idx] == target) {
if (ans[1] == -1 || ans[1] < end_idx) {
ans[1] = end_idx;
}
if (ans[0] == -1) {
ans[0] = end_idx;
}
}
}
return;
}
vector<int> searchRange(vector<int>& nums, int target) {
if (nums.size() == 0)
return ans;
searchMid(nums, target, 0, nums.size() - 1);
return ans;
}
};