思路一:因为是升序的排序,而且题目要求时间复杂度为O(logn),所以就可以想到用二分查找,但是与普通的二分查找不同的就是数组中目标值可能有不同,所以先考虑找到目标值然后再以这个找到的位置为基准然后找左右边界。
思路二:用两次二分查找,找左边界的时候要用右边界right进行逼近,找右边界的时候要用左边界left进行逼近。
class Solution{
//这个思路一的版本:
public int[] searchRange(int[] nums, int target) {
//先找看看能不能找到目标值
int mid = searchTarget(nums, target);
if(mid == -1){
//找不到直接返回-1
return new int[]{-1, -1};
}
int left = mid;
int right = mid;
//找左右边界
while(left-1>=0 && nums[left-1] == nums[mid]){
left-=1;
}
while(right+1<nums.length && nums[right+1] == nums[mid]){
right+=1;
}
return new int[]{left, right};
}
//普通的二分查找
public int searchTarget(int[] nums, int target){
int left = 0;
int right = nums.length - 1;
//用左边右闭的方法
while(left<=right){
int middle = left + (right - left) / 2;
if(nums[middle]<target){
left = middle + 1;
}else if(nums[middle]>target){
right = middle - 1;
}else{
return middle;
}
}
return -1;
}
}
时间复杂度:O(logn)
空间复杂度:O(1)
此文为阅读’代码随想录‘的leetcode刷题所写笔记。代码参考作者’程序员Carl‘(代码随想录)
参考:代码随想录