二分查找闭区间模板
例题:力扣34
题目描述及例子:
例子1的转化描述:
解题思路:
使用二分查找才能满足题目时间复杂度的要求,算法思想是从中间开始找,每一次就能获得n/2的信息(确定目标值在左边还是右边)。
Py二分模板
def low_bound(nums: List[int], target: int)-> List[int]:
right = len(nums) - 1 # 闭区间 [left, right]
left = 0
while left <= right: # 区间不为空
# 其他语言防止溢出 mid = left + (right - left) // 2
mid = (left + right) // 2 # 除2向下取整
if nums[mid] < target:
left = mid + 1 # [mid + 1, right]
else:
right = mid - 1 # [left, mid - 1]
return left
Ps:如果nums数组中没有target值的话,返回的是数组中比target大的那个区间中的第一个索引。
例如:[-2,-1,-1,1,2,3]中,如果我的target = 0,则找不到目标值,返回的值是3,即找到的是数字1所在的下标。
Py解题模板
要找到target的范围,就要明白二分模板返回的left的含义是指最开始出现的target值,也就是相同值的最左边。(与下标left保持一致)
对于例子1来说:
找8的值 转变为 找 >= 8的值和 < 9 的值(8第一次出现的值和9第一次出现的值之间)
一般化:
找target相当于 找target第一次出现的值和第一次出现target+1的值的索引-1
扩展二分查找
四种情况:(找targ)
找 大于等于target的数 即 二分模板(找target第一次出现的索引,这个索引之后的数满足要求)
找 大于target的数(不包括target) 即找target+1(转换为找大于等于 target+1的数 ,满足模板)
找小于target的数 即找target第一次出现的索引-1
找小于等于target的数 即找小于target+1的数
解题
理解这四种情况,就能解题啦。题目意思就是找大于等于target的数字且小于target+1的数字,即target的范围!
def low_bound(nums: List[int], target: int)-> List[int]:
right = len(nums) - 1 # 闭区间 [left, right]
left = 0
while left <= right: # 区间不为空
# 其他语言防止溢出 mid = left + (right - left) // 2
mid = (left + right) // 2 # 除2向下取整
if nums[mid] < target:
left = mid + 1 # [mid + 1, right]
else:
right = mid - 1 # [left, mid - 1]
return left
class Solution:
def searchRange(self, nums: List[int], target: int) -> List[int]:
start = low_bound(nums, target)
if start >= len(nums) or nums[start] != target :
return [-1, -1]
end = low_bound(nums, target + 1) - 1
return [start, end]
参考链接
可能描述的不够准确,这下面是直观的视频链接说明。
二分视频链接