题目:
给你一个按照非递减顺序排列的整数数组
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]
解题思路:
看到题目,我的第一反应是使用二分查找法来解题,因为本题的数组是有序排列的。
二分查找的思想:比较数组的中间值mid与目标值target,如果mid>target,则在数组的右边部分继续查找,直到找到目标值或查找区间为空为止;如果mid=target,则找到目标值了,直接返回mid;如果mid<target,则在数组的左边部分继续查找,直到找到目标值或查找区间为空为止。
代码(通过理解力扣题解与智普清言的回答写出)
class Solution:
def binarySearch(self, nums, target, lower):
left = 0
right = len(nums) - 1
ans = len(nums)
while left <= right:
mid = (left + right) // 2
if nums[mid] > target or (lower and nums[mid] >= target):
right = mid - 1
ans = mid
else:
left = mid + 1
return ans
def searchRange(self, nums, target):
leftIdx = self.binarySearch(nums, target, True)
rightIdx = self.binarySearch(nums, target, False) - 1
if leftIdx <= rightIdx and rightIdx < len(nums) and nums[leftIdx] == target and nums[rightIdx] == target:
return [leftIdx, rightIdx]
return [-1, -1]
代码详解:
binarySearch
方法:
- 参数
nums
是排序后的数组。- 参数
target
是要查找的目标值。- 参数
lower
表示是否是查找下界,如果是True
,则表示查找目标值的起始位置(左边界),否则表示查找目标值的结束位置(右边界)。- 函数返回的是目标值在数组中的位置索引。
这个方法使用了二分查找的思想,在有序数组中查找目标值的位置。
- 初始化左右指针
left
和right
分别指向数组的起始和末尾位置。ans
变量用于记录目标值的位置,初始化为数组长度,作为一个足够大的数。def binarySearch(self, nums, target, lower): left = 0 right = len(nums) - 1 ans = len(nums)
- 进入循环,当
left
小于等于right
时执行:
- 计算中间位置
mid
。- 如果
nums[mid]
大于目标值target
或者(对于下界查找)lower
为真且nums[mid]
大于等于target
,则更新right
和ans
,缩小查找范围到左半边。- 否则,更新
left
,缩小查找范围到右半边。- 返回
ans
,即目标值的位置索引。while left <= right: mid = (left + right) // 2 if nums[mid] > target or (lower and nums[mid] >= target): right = mid - 1 ans = mid else: left = mid + 1 return ans
searchRange
方法:
- 参数
nums
是排序后的数组。- 参数
target
是要查找的目标值。- 该方法使用
binarySearch
方法两次,分别查找目标值的起始位置和结束位置。- 返回的是目标值在数组中的起始位置和结束位置组成的列表
[leftIdx, rightIdx]
。在主程序中:
- 调用
binarySearch
方法两次,分别查找目标值的起始位置leftIdx
和结束位置rightIdx
。- 检查起始位置和结束位置是否合法,以及起始位置和结束位置的值是否都等于目标值,如果满足条件,则返回
[leftIdx, rightIdx]
,否则返回[-1, -1]
表示未找到目标值。def searchRange(self, nums, target): leftIdx = self.binarySearch(nums, target, True) rightIdx = self.binarySearch(nums, target, False) - 1 if leftIdx <= rightIdx and rightIdx < len(nums) and nums[leftIdx] == target and nums[rightIdx] == target: return [leftIdx, rightIdx] return [-1, -1]
通过此题,我了解到了lower是一个布尔型参数,用于表示是否是查找目标值的下界(左边界)。当lower为true时,表示查找目标值的起始位置,当lower为false时,表示查找目标值的结束位置。
第一次写博客,希望大家多多提意见,如果觉得我写的还不错的话,留下一个小小的赞啵!