给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
进阶:
你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗?
首先处理特殊情况:列表为空或者其中只有1个元素的情况;
接着采用变形的二分法,搜索区间确定为左闭右开,查找列表中目标值出现的起始位置(或者小于目标值的数的个数);
接着修改目标值为 target+1 ,再次查找小于目标值的数的个数,处理边界情况。
提交通过的python代码如下:
class Solution(object):
def findLeft(self,nums,target):
length = len(nums)
#左闭右开 搜索区间是[0,length)
start = 0
end = length
mid = (int)((start+end)/2)
while start<end:
if nums[mid]==target:
end = mid
elif nums[mid]<target:
start = mid + 1
elif nums[mid]>target:
end = mid
mid = (int)((start + end)/2)
return start
def searchRange(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
ans = []
if len(nums)==0:
ans.append(-1)
ans.append(-1)
return ans
elif len(nums)==1:
temp =0
if nums[0]!=target:
temp = -1
ans.append(temp)
ans.append(temp)
return ans
zuo = self.findLeft(nums,target)
you = self.findLeft(nums,target+1)
if zuo <0 or zuo>=len(nums):
ans.append(-1)
ans.append(-1)
elif nums[zuo]!=target:
ans.append(-1)
ans.append(-1)
else :
you= you-1
ans.append(zuo)
ans.append(you)
return ans
详细注释如下:
nums = [5,7]
target = 7
# 找出比目标值小的数有多少个
def findLeft(nums,target):
length = len(nums)
#左闭右开 搜索区间是[0,length)
start = 0
end = length
mid = (int)((start+end)/2)
while start<end:
if nums[mid]==target:
end = mid
# 不断向左压缩,因为右边是开区间,所以把已经满足要求的mid排除了一个
elif nums[mid]<target:
start = mid + 1
# 左边是闭区间,所以在[mid+1,end)里面继续查找,mid已经不满足了
elif nums[mid]>target:
end = mid
# 右边是开区间,所以在[left,mid)里面继续查找,mid已经不满足了
mid = (int)((start + end)/2)
return start
def searchRange(nums, target):
ans = []
if len(nums)==0:
ans.append(-1)
ans.append(-1)
return ans
elif len(nums)==1:
temp=0
if nums[0]!=target:
temp = -1
ans.append(temp)
ans.append(temp)
return ans
zuo = findLeft(nums,target)
you = findLeft(nums,target+1)
if zuo <0 or zuo>=len(nums):
ans.append(-1)
ans.append(-1)
elif nums[zuo]!=target:
ans.append(-1)
ans.append(-1)
else :
you= you-1
ans.append(zuo)
ans.append(you)
return ans
print(searchRange(nums,target))