二分法的边界问题
二分法是一种快速的搜索策略,在有序数组中选取中间位置进行判断,每一轮的搜索可以删除一半的数据域,从而将搜索的时间复杂度降为
O
(
l
o
g
n
)
O(log n)
O(logn)。但在利用二分法编写程序时,尤其需要注意二分法的边界条件,属于容易出错的细节问题。
一般二分法有两种方式实现对边界的控制,分别是左闭右闭和左闭右开。
方式一:左闭右闭
如果二分查找的范围是一个左闭右闭区间[left,right],while循环的结束控制条件应该是left<=right,此时需要使用<=,因为left==right在闭区间内是有意义的。
一轮查找后对边界进行收缩,如果nums[mid]<target,则目标一定在mid之后,设定left=mid+1;若nums[mid]>target,则目标一定在mid之前,设定right=mid-1。
def search(nums, target):
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
return mid
if nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
方式二:左闭右开
如果二分查找的范围是一个左闭右开区间[left,right),while循环的结束控制条件应该是left<right,此时需要使用<,因为left==right在左闭右开区间内是没有意义的。
一轮查找后对边界进行收缩,如果nums[mid]<target,则目标一定在mid之后,设定left=mid+1;若nums[mid]>target,则目标一定在mid之前,但由于right是不可取到的,设定right=mid。
def search(nums, target):
while left < right:
mid = left + (right - left) // 2
if nums[mid] == target:
return mid
if nums[mid] < target:
left = mid + 1
else:
right = mid
return -1
例题
704.二分查找
给定一个n个元素有序的(升序)整型数组nums和一个目标值target,写一个函数搜索nums中的target,如果目标值存在返回下标,否则返回-1。示例1:
输入:nums = [-1,0,3,5,9,12], target = 9
输出:4示例2:
输入:nums = [-1,0,3,5,9,12], target = 2
输出:-1提示:
- 你可以假设
nums中的所有元素是不重复的。n将在[1,10000]之间。nums的每个元素都将在[-9999,9999]之间。
写法一:左闭右闭
class Solution:
def search(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums)-1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
return mid
if nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
写法二:左闭右开
class Solution:
def search(self, nums: List[int], target: int) -> int:
left, right = 0, len(nums)
while left < right:
mid = left + (right - left) // 2
if nums[mid] == target:
return mid
if nums[mid] < target:
left = mid + 1
else:
right = mid
return -1
文章详细介绍了二分法在处理有序数组搜索时的两种边界处理方式,分别是左闭右闭和左闭右开,并提供了对应的Python代码实现。二分法通过每轮删除一半数据域来达到O(logn)的时间复杂度,但需注意边界条件的正确设置,以避免错误。文章还给出了一道关于二分查找的示例题目。
3127

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



