给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。
你的算法时间复杂度必须是 O(log n) 级别。 如果数组中不存在目标值,返回 [-1, -1]。
示例 1:输入: nums = [5,7,7,8,8,10], target = 8
输出: [3,4]来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array
方法1:二分查找法
利用二分查找法查找左右边界
更多关于二分查找的讲解可以看这里:https://labuladong.gitbook.io/algo/di-ling-zhang-bi-du-xi-lie/er-fen-cha-zhao-xiang-jie
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
def left_boundary(nums,target):
left=0
right=len(nums)-1
# 确认左侧边界
while left<=right:
mid=left+(right-left)//2
if nums[mid]>target:
right=mid-1
elif nums[mid]<target:
left=mid+1
else:
right=mid-1 # 注意,此处与查找右边界的不同
if (left>=len(nums)) or nums[left]!=target: # 注意,此处与查找右边界的不同
return -1
return left
def right_boundary(nums,target):
left=0
right=len(nums)-1
# 确认右侧边界
while left<= right:
mid=left+(right-left)//2
if nums[mid]>target:
right=mid-1
elif nums[mid]<target:
left=mid+1
else:
left=mid+1 # 注意,此处与查找左边界的不同
if right<0 or nums[right]!=target: # 注意,此处与查找左边界的不同
return -1
return right
l=left_boundary(nums,target)
r=right_boundary(nums,target)
return [l,r]
方法2:将方法1的left和right函数放入一个函数中
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
if len(nums) == 0: return [-1,-1]
left = self.helper(nums, target, True)
# left是否找到
if left == len(nums) or nums[left] != target:
return [-1,-1]
return [left, self.helper(nums, target, False)-1]
def helper(self, nums, target, isLeft):
'''
nums:待查数列
target:目标值
isLeft:是否是左侧边界
'''
low = 0
high = len(nums) - 1
while(high >= low):
mid = (high + low) // 2
# 如何寻找最左边的target,碰见了以后依然往左递归。
if nums[mid] > target or (isLeft and nums[mid] == target):
high = mid - 1
else:
low = mid + 1
return low