二分查找最常用场景: (1) 寻找一个数 (2) 寻找左侧边界 (3) 寻找右侧边界 注意点: (1) l与r的初始值 (2) while里的判断语句是否有等号 (3) target与mid大小比较后, l与r的赋值 明确搜索区间是最重要的 ''' class Solution(object): # (1) 二分查找 # 搜索区间: [left,right] 搜索区间两端闭合 def search(self, nums, target): """ :type nums: List[int] :type target: int :rtype: int """ l = 0 r = len(nums)-1 # 搜索区间两端闭合,初始区间[0,len(nums)-1], # 左右区间都必须是有意义的,nums[len(nums)]这个元素是不存在的 while l <= r: # 搜索区间两端闭合,不能忽略[l,r]中l==r的情况 # mid = (l+r)//2 mid = l + (r-l)//2 # 计算mid时需要防止溢出,代码中(l+r)//2与l+(r-l)//2结果相同,但后者有效防止了l和r太大直接相加导致溢出。 if target > nums[mid]: l = mid + 1 # 搜索区间两端闭合,mid已经考虑过了,下次考虑的区间: [mid+1,r] elif target < nums[mid]: r = mid -1 # 搜索区间两端闭合,mid已经考虑过了,下次考虑的区间: [l,mid-1] else: return mid return -1 # (2) 寻找左侧边界 # 搜索区间: [left,right] 搜索区间两端闭合 def searchLeft(self, nums, target): l = 0 r = len(nums)-1 while l <= r: mid = l + (r-l)//2 if target < nums[mid]: r = mid - 1 # 搜索区间变为 [l,mid-1] elif target > nums[mid]: l = mid + 1 # 搜索区间变为 [mid+1,r] elif target == nums[mid]: r = mid - 1 # 找到target时不要立即返回,而是缩小「搜索区间」的上界r,在区间 [l, mid] 中继续搜索,即不断向左收缩,达到锁定左侧边界的目的。 # while终止条件为 l > r,就有可能出现l越界的可能,因此要对边界进行处理 # 检查出界情况 if (l >= nums.length or nums[l] != target): return -1 return l # (3) 寻找右侧边界 # 搜索区间: [left,right] 搜索区间两端闭合 def searchRight(self, nums, target): l = 0 r = len(nums)-1 while l <= r: mid = l + (r-l)//2 if target < nums[mid]: r = mid - 1 # 搜索区间变为 [l,mid-1] elif target > nums[mid]: l = mid + 1 # 搜索区间变为 [mid+1,r] elif target == nums[mid]: l = mid + 1 # 收缩左侧边界 # 这里改为检查right越界的情况 if (r < 0 or nums[r] != target): return -1 return r
python leetcode 704 二分查找 【简单题】
最新推荐文章于 2025-03-26 15:54:38 发布