二分查找中处理边界条件,避免死循环
2026/4/23 12:12:40 网站建设 项目流程
def halfcheck(self,strs,start,minl): start = start end =minl while start<end: lengthmid =(end-start+1)//2+start if self.isCommonPrefix(strs,lengthmid): start =lengthmid else: end = lengthmid-1 return strs[0][:start]

当换成lengthmid =(end-start)//2+start就可能存在问题

指出的这个细节非常关键。这是二分查找中处理边界条件时的常见问题。

问题分析

原始代码:(end-start+1)//2+start

这是向上取整的计算方式:

  • end-start+1是奇数时,中点偏右
  • end-start+1是偶数时,取两个中间点中靠右的那个
  • 这能避免死循环

修改后:(end-start)//2+start

这是向下取整的计算方式:

  • end-start+1是偶数时,中点偏左
  • 在某些边界条件下会导致死循环

例子说明

假设start=0,end=1,查找区间是[0,1]

原始代码(向上取整):

lengthmid=(1-0+1)//2+0=2//2+0=1+0=1# 检查位置1

修改后(向下取整):

lengthmid=(1-0)//2+0=1//2+0=0+0=0# 检查位置0

死循环场景

假设我们要检查前缀长度,startend相邻时:

# 场景:start=0, end=1whilestart<end:# 0 < 1,进入循环# 向下取整lengthmid=(1-0)//2+0=0if条件满足:# 假设这个条件在lengthmid=0时成立start=lengthmid# start = 0,没有变化!else:end=lengthmid-1# 不会执行# 现在 start=0, end=1,又回到了循环开始的状态# 死循环!

正确做法

方案1:保持向上取整(你的原始代码)

lengthmid=(end-start+1)//2+start

方案2:修改循环条件和更新逻辑

defhalfcheck(self,strs,start,minl):left,right=start,minlwhileleft<=right:# 改为 <=mid=(right-left)//2+leftifself.isCommonPrefix(strs,mid):# 向右查找left=mid+1else:# 向左查找right=mid-1returnstrs[0][:right]# 注意返回right

总结

代码使用(end-start+1)//2+start正确的,这是为了避免在二分查找时陷入死循环。改为向下取整在某些边界条件下确实会导致问题。

核心原则:二分查找中,mid的计算、循环条件、边界更新必须三者一致,否则可能死循环或漏查。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询