二分查找中的小细节
主要参考《代码随想录》
力扣链接:704. 二分查找
二分查找,虽然思想非常简单,但是边界值的处理经常出问题。主要有以下两个方面:
例如到底是 while(left < right) 还是 while(left <= right),到底是right = middle呢,还是要right = middle - 1呢?
其实这两种方法都可以实现,选择哪种写法关键在于区间是如何定义的。
写二分法,区间的定义一般为两种,左闭右闭即[left, right],或者左闭右开即[left, right)。
举个例子,比如说有一个数组名为nums = [2,3,5,1,4]
那么以下写法为左闭右开:
nums = [2,3,5,1,4]
left = 0
right = len(nums)
#left = 0,right = 5
数组的合法下标是0,1,2,3,4.并不能取到5,所以是左闭右开区间。
同理,以下写法是左闭右闭区间
nums = [2,3,5,1,4]
left = 0
right = len(nums) - 1
#left = 0,right = 4
在后续的代码中,都要保持区间的一致性。
左闭右开区间
对于左闭右开区间,left == right是不合法的,所以在while中写的时候应该写为while(left < right) 而在mid更新时,由于mid已经被检验过,肯定在区间外。所以若需更新left:left = mid+1,若需更新right:right = mid
class Solution:
def search(self, nums: List[int], target: int) -> int:
begin = 0
end = len(nums)
mid = (begin+end)//2
while(begin<end):
if(nums[mid] == target):
return mid
elif nums[mid]>target:
end = mid
else:
begin = mid + 1
mid = (begin+end)//2
return -1
左闭右闭区间
对于左闭右闭区间,left == right是合法的,所以在while中应该写为:while(left <= right)而在mid更新时,由于mid已经被检验过,肯定在区间外。所以若需更新left:left = mid+1,若需更新right:right = mid-1
class Solution:
def search(self, nums: List[int], target: int) -> int:
begin = 0
end = len(nums)-1
mid = (begin+end)//2
while(begin<=end):
if(nums[mid] == target):
return mid
elif nums[mid]>target:
end = mid - 1
else:
begin = mid + 1
mid = (begin+end)//2
return -1
本文讨论了在实现二分查找算法时,针对左闭右开和左闭右闭两种区间定义的细微差别,包括while循环条件和中期点更新的方法,强调了保持区间定义一致性的必要性。
4271

被折叠的 条评论
为什么被折叠?



