搜索范围
给定一个按照升序排列的整数数组 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]
分析
这道题思想还是基于二分查找,最通常情况下,我们用来寻找排序数组中的特定值;而这道题是要找范围,也就是说我们再通常条件下向左右两端扩展即可,也就是说我们需要对每次左右两部分都进行一次二分查找。
代码参考网上。
代码
class Solution {
public int[] searchRange(int[] nums, int target) {
//参考网上代码
//依旧是二分,不过需要两端都进行二分,分别找开始位置和结束位置
int[] res = {-1,-1};
if(nums.length==0){
return res;
}
//第一个(大于)等于target的元素数组下标
int left = searchLeft(nums,target,0,nums.length-1);
//最后一个(小于)等于target的元素数组下标
int right = searchRight(nums,target,0,nums.length-1);
if(right>=left){
res[0]=left;
res[1]=right;
}
return res;
}
//找从左到右第一个target对应元素的数组下标,当target不存在时,找到第一个大于target的元素的数组下标
private int searchLeft(int[] nums,int target,int begin,int end){
if(begin > end){
return begin;
}
int mid = begin +(end-begin)/2;
if(nums[mid]<target)
return searchLeft(nums,target,mid+1,end);
else
return searchLeft(nums,target,begin,mid-1);
}
//找从右到左第一个target对应元素的数组下标,当target不存在时,找到第一个小于target的元素的数组下标
private int searchRight(int[] nums,int target,int begin,int end){
if(begin > end){
return end;
}
int mid = begin +(end-begin)/2;
if(nums[mid]<=target)
return searchRight(nums,target,mid+1,end);
else
return searchRight(nums,target,begin,mid-1);
}
}