解法1:双指针
思路:从左向右遍历即可。
易错点:
1:长度为0时单独判断
2:更新right时,index可能移动到n,此时也需要单独考虑
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
vector<int> ans;
int left = -1, right = -1;
int n = nums.size();
if (n == 0) { //长度为0单独判断!!!
ans.push_back(-1);
ans.push_back(-1);
return ans;
}
int index;
for (index = 0; index < n; ++index) {
if (nums[index] == target) {
if (index == 0 || nums[index - 1] != target) {
left = index;
}
}
if (nums[index] > target) {
if (index == 0 || nums[index - 1] == target) {
right = index - 1;
}
break;
}
}
if (index == n && nums[index - 1] == target) { //别忘了移动到最后的情况 !!!
right = index - 1;
}
ans.push_back(left);
ans.push_back(right);
return ans;
}
};
解法2:二分
思路:分别找到大于等于tagert 大于tagert的位置
易错点:
1:二分要考虑好边界(数组长度为0单独考虑),比如:return right;right在n的位置有什么特殊情况,不在n时有什么特殊情况?
2:return right - 1时,right在n的位置有什么特殊情况,不在n时有什么特殊情况,当right在0时会出现什么情况?
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
vector<int> ans;
int n = nums.size();
if (n == 0) {
ans.push_back(-1);
ans.push_back(-1);
return ans;
}
int left = -1, right = n;
while (left + 1 < right) { //找到right
int mid = left + (right - left) / 2;
if (nums[mid] >= target) {
right = mid;
}else left = mid;
}
//一种特殊情况是到结尾,一种是不到结尾,应该用else if连接,而不能用两个串联的if!!!
if (right == n) {
right = -1;
}else if (nums[right] != target) {
right = -1;
}
int l = -1, r = n;
while (l + 1 < r) { //找到r
int mid = l + (r - l) / 2;
if (nums[mid] > target) {
r = mid;
}else l = mid;
}
if (r == n && nums[r - 1] != target) {
r = 0;
}else if (r != 0 && nums[r - 1] != target) r = 0;
//r有可能在下标0的位置,此时也属于数组中间的位置,所以要加上判断r != 0!!!
ans.push_back(right);
ans.push_back(r - 1);
return ans;
}
};