题目描述
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
你的算法时间复杂度必须是O(log n) 级别。
如果数组中不存在目标值,返回[-1, -1]。
样例
输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]
算法
(二分) $O(logn)$
- 第一次二分查找第一个位置使得它的值 大于等于 target,若该位置的值不等于 target,则返回 [-1, -1]。
- 第二次二分查找第一个位置使得它的值 大于 target。注意需要特判边界。
Java 代码
public int[] searchRange(int[] nums, int target) {
//定义输出数组
int[] output = new int[]{-1,-1};
//特判
if(nums == null || nums.length == 0)
return output;
/*二分法找左边界,这里有一个细节是为什么check是nums[mid] >= target ,寻找的就是左边界?
可以画图表示,寻找左边界表示我要从右向左进行收缩,那么check后满足条件,应该首先改变r
*/
int l = 0, r = nums.length - 1;
while (l < r)
{
int mid = l + r >> 1;
if(nums[mid] >= target) r = mid;
else
l = mid + 1;
}
if(nums[r] != target) return output;
output[0] = l;
l = 0;
r = nums.length - 1;
/*二分法找左边界,这里有一个细节是为什么check是nums[mid] <= target ,寻找的就是右边界?
可以画图表示,寻找右边界表示我要从左向右进行收缩,那么check后满足条件,应该首先改变l
*/
while(l < r)
{
int mid = l + r + 1>> 1;
if(nums[mid] <= target) l = mid;
else
r = mid - 1;
}
output[1] = r;
return output;
}