思路:
要求复杂度nlogn,直接遍历复杂度是n,要用二分查找
注意边界上下取整!
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
if len(nums)==0:
return [-1,-1]
l=self.findleft(nums,target)
if l==-1:
return [-1,-1]
r=self.findright(nums,target)
return [l,r]
def findleft(self,nums,target):
left=0
right=len(nums)-1
while left<right:
mid = left + (right - left) // 2#用/2会出现小数
if nums[mid]<target:
left=mid+1
elif nums[mid]==target:#mid是一个目标,mid前可能还有
right=mid
else:
#nums[mid]>target
right=mid-1
if nums[left] == target:
return left
else:
return -1
def findright(self,nums,target):
left=0
right=len(nums)-1
while left<right:
mid = left + (right - left + 1) // 2
if nums[mid]>target:
right=mid-1
elif nums[mid]==target:#mid是一个目标,mid后可能还有
left=mid
else:
#nums[mid]<target
left=mid+1
return left#如果l存在,那r肯定存在
class Solution {
public int[] searchRange(int[] nums, int target) {
int[] res=new int[2];
res[0]=-1;res[1]=-1;
if(nums.length==0){
return res;
}
int l=findleft(nums,target);
if(l==-1){
return res;
}
int r=findright(nums,target);
res[0]=l;res[1]=r;
return res;
}
public int findleft(int[] nums,int target){
int left=0,right=nums.length-1;
while(left<right){
int mid=(left+right)/2;
if(nums[mid]==target){
right=mid;
}
else if(nums[mid]<target){
left=mid+1;
}
else{
right=mid-1;
}
}
return nums[left]==target?left:-1;
}
public int findright(int[] nums,int target){
int left=0,right=nums.length-1;
while(left<right){
int mid=(left+right+1)/2;
if(nums[mid]==target){
left=mid;
}
else if(nums[mid]<target){
left=mid+1;
}
else{
right=mid-1;
}
}
return right;
}
}
right = mid
和left = mid + 1
和mid = left + (right - left) / 2
;一定是配对出现的;right = mid - 1
和left = mid
和mid = left + (right - left + 1) /2
; 一定是配对出现的。
整合一下比较规整的形式:
class Solution {
public int[] searchRange(int[] nums, int target) {
int[] res=new int[2];
res[0]=-1;res[1]=-1;
if(nums.length==0) return res;
int left=0,right=nums.length-1;
while(left<right){
int mid=(left+right)/2;
if(target<=nums[mid]) right=mid;
else left=mid+1;
}
if(nums[left]!=target) return res;
int i=left,j=nums.length-1;
while(i<j){
int mid=(i+j+1)/2;
if(target>=nums[mid]) i=mid;
else j=mid-1;
}
res[0]=left;
res[1]=j;
return res;
}
}