1、题目描述:
2、题解:
线性扫描
我们首先想到的是线性扫描,从前往后遍历:查找左端点,从后往前遍历:查找右端点。
二分查找:
二分查找模板:参看这篇文章算法思想 从0到1:分治法——二分查找模板小结(三种:第一种基础,推荐掌握第一种,第三种是第二种的变体)
定义一个函数,找目标值的右端点;然后找目标值的下一个值的右端点,找目标值的右端点。
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
if nums == []:
return [-1, -1]
# 找右端点
def find_right(nums, target):
left, right = 0, len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] < target:
left = mid + 1
elif nums[mid] > target:
right = mid - 1
else:
left = mid + 1
return right
left = find_right(nums, target - 1) #找目标值的下一个值的右端点
right = find_right(nums, target)#找目标值的右端点
return [left + 1, right] if right - left > 0 else [-1, -1]
或者:
直接用两次二分查找,
1)查找目标值的左端点:
把模板稍微做一下改变:当相等时,right = mid - 1,表示在左边继续查找;
2)查找目标值的右端点:
把模板稍微做一下改变:当相等时,left= mid + 1,表示在右边继续查找;
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
if not nums: return [-1,-1]
#找左端点
left,right = 0,len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] < target:
left = mid + 1
elif nums[mid] > target:
right = mid - 1
elif nums[mid] == target:
right = mid - 1
l = left
#找右端点
left,right = 0,len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] < target:
left = mid + 1
elif nums[mid] > target:
right = mid - 1
elif nums[mid ] == target:
left = mid + 1
r = right
return [l,r] if l <= r else [-1,-1]
3、复杂度分析:
时间复杂度:O(logN)
空间复杂度:O(1)