难度:中等
题目要求:
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
如果数组中不存在目标值 target,返回 [-1, -1]。
进阶:你可以设计并实现时间复杂度为 O(log n) 的算法解决此问题吗?
示例 1:
输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]
示例 2:
输入:nums = [5,7,7,8,8,10], target = 6
输出:[-1,-1]
示例 3:
输入:nums = [], target = 0
输出:[-1,-1]
最简单的办法肯定是暴力解决了,代码如下:
def searchRange1(nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
start_end = [-1,-1]
if len(nums)==0:
return start_end
for i in range(0,len(nums)):
if nums[i]==target:
if start_end[0] == -1:
start_end[0] = i
start_end[1] = i
elif start_end[1] < i:
start_end[1]=i
return start_end
看了题解发现进阶版是使用二分查找,要注意的小细节还是挺多的,一开始自己没有写出来,认真看了一下题解:
#找第一个位置
def findFirstNumber(nums,target):
left = 0
right = len(nums)-1
while left<right:
middle = (left + right) // 2
# print(middle)
if nums[middle] < target:
left = middle+1
elif nums[middle] > target:
right = middle -1
elif nums[middle] == target:
right = middle #注意此处,可继续查找第一个出现的元素位置
if nums[left]==target: #判断一次是否成功找到
return left
return -1
#找最后一个位置
def findLastNumber(nums,target):
left = 0
right = len(nums)-1
while left<right:
middle = (left + right+1) // 2 #这里要加1,不然会陷入死循环
# print(middle)
if nums[middle] < target:
left = middle+1
elif nums[middle] > target:
right = middle -1
elif nums[middle] == target:
left = middle #注意此处,可继续查找最后出现的元素位置
#由于找到了第一个元素位置,所以直接返回最后一个元素位置
return right
def searchRange(nums,target):
if len(nums)==0:
return [-1,-1]
left = findFirstNumber(nums,target)
if left == -1:
return [-1,-1]
right = findLastNumber(nums,target)
return [left,right]
提交结果:第一行是二分查找的提交效果,第二行是暴力法的提交效果。