题目描述:给定一个按照升序排列的整数数组 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]
解析:二分查找
算法:找最左和最右下标的方法。首先,为了找到最左边(或者最右边)包含 target 的下标(而不是找到的话就返回 true ),所以算法在我们找到一个 target 后不能马上停止。我们需要继续搜索,直到 low == high 且它们在某个 target 值处下标相同。
另一个是 flag参数的引入,它是一个 boolean 类型的变量,指示我们在遇到 target == nums[mid] 时应该做什么。如果 left 为 true ,那么我们递归查询左区间,否则递归右区间。考虑如果我们在下标为 i 处遇到了 target ,最左边的 target 一定不会出现在下标大于 i 的位置,所以我们永远不需要考虑右子区间。当求最右下标时,道理同样适用。
class Solution {
private int binarySearch(int[] nums,int target,boolean flag){
int low = 0,high = nums.length;
while(low < high){
int mid = low + (high - low)/2;
if(nums[mid] > target || (flag && nums[mid] == target)){
high = mid;
}else{
low = mid + 1;
}
}
return low;
}
public int[] searchRange(int[] nums, int target) {
int[] ret ={-1,-1};
int left = binarySearch(nums,target,true);
if(left == nums.length || target != nums[left]){
return ret;
}
ret[0] = left;
ret[1] = binarySearch(nums,target,false) - 1;
return ret;
}
}