LeetCode34-在排序数组中查找元素的第一个和最后一个位置
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
你的算法时间复杂度必须是 O(log n) 级别。
如果数组中不存在目标值,返回 [-1, -1]。
示例 1:
输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]
示例 2:
输入: nums = [5,7,7,8,8,10], target = 6
输出: [-1,-1]
一、思路
(一)二分查找
首先通过二分查找找到val的值,然后向左、向右移动,找到边界,输出即可
出错1:忘记考虑边界
由于每次都只比较中间值,所以一开始的边界(0,length-1)没有参与比较,而又因为整型数会向下取整,最后会导致右边界没有参与比较,导致结果错误
C++代码如下:
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
if (nums.empty())
return { -1,-1 };
int i = 0, j = nums.size() - 1;
if (target > nums[j] || target < nums[i])
return { -1,-1 };
int min = (target == nums[i]) ? i : -1, max = (target == nums[j]) ? j : -1;
if (min != -1 && max != -1)
return { min,max };
else if (min != -1) {
int m = min;
while (m < nums.size() && nums[m] == target)
m++;
max = m - 1;
}
else if (max != -1) {
int m = max;
while (m >= 0 && nums[m] == target)
m--;
min = m + 1;
}
else {
int k, m;
while (i < j) {
m = (i + j) / 2;
if (nums[m] == target) {
k = m;
break;
}
if (m == i)
return { -1,-1 };
if (nums[m] > target)
j = m;
else
i = m;
}
m = k;
while (m >= 0 && nums[m] == target)
m--;
min = m + 1;
while (k < nums.size() && nums[k] == target)
k++;
max = k - 1;
}
return { min,max };
}
};
执行效率: