难度:中等
给定一个按照升序排列的整数数组 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]
思路:因为有时间复杂度的要求,所以需要二分法来完成,这个主要牵扯到一个边界寻找问题,即二分法查找目标数的左边界和有边界,详细请看代码中注释即可。同时提供一个普通遍历查找的方法,即设置标记量flag=0,如果找到了且flag=0,则改变标记了,并且记录此时位置(数组两个数字均记录,防止仅一个的情况)然后再次查询到时更改数组第二个数字,最后数组记录的即答案所求位置
代码1(二分法,打败80%+):
class Solution(object):
def searchRange(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
if len(nums)==0:
return [-1,-1]
#默认-1,-1
left,right = -1,-1
#找左边界
start,end =0,len(nums)-1
while start+1<end:
mid=start+((end-start)/2)
#只要是中间轴大于大于等于目标值,则end左移,结果一定卡在左边界上
if nums[mid]>=target:
end=mid
else:
start=mid
#此时可能保留两个数 不一定谁是左边界,所以都判断一下,也可能都是,这样start后判断即可
if target==nums[end]:
left=end
if target==nums[start]:
left=start
#找有边界
start,end=0,len(nums)-1
while start+1<end:
#同理
mid=start+((end-start)/2)
if nums[mid]<=target:
start=mid
else:
end=mid
#同上,此时需要end后判断
if target==nums[start]:
right=start
if target==nums[end]:
right=end
return [left,right]
代码2(普遍遍历法,打败70%+):
class Solution(object):
def searchRange(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
if len(nums)==0:
return [-1,-1]
flag=0
list1=[-1,-1]
for i in range(len(nums)):
if nums[i]==target:
if flag==0:
flag=1
list1[0],list1[1]=i,i
else:
list1[1]=i;
return list1