在二进制搜索中,为什么 mid = (left + (right - left)) // 2 比 mid = (left + right) // 2 好?
In Binary search why doing mid = (left + (right - left)) // 2 is better than mid = (left + right) // 2?
在二分查找 while 循环中:
left, right = 0, len(nums)
while left < right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
为什么在 python 以外的某些语言中 mid = (left + (right - left)) // 2
比 mid = (left + right) // 2
更好?
编辑:好像我把括号弄错了。感谢您指出这一点,它对我来说更清楚了。我会这样离开,以防其他人偶然发现这一点。我在 youtube 视频中看到了这个评论,但是那个人从来没有解释为什么一个会比另一个更好。谢谢大家的回答!
谢谢大家!
如果值对于它们的 int
表示而言太高,left + right
可能会溢出。有关详细信息,请参阅 Extra, Extra - Read All About It: Nearly All Binary Searches and Mergesorts are Broken。
这是 C 等语言中的一个问题,其中 int
变量有限制,但 Python 中没有。使用更直接的代码应该没问题。
好吧,你把括号弄错了。我会让你弄明白的。
但是要回答你的问题:
在 Python 中没关系,因为整数可以根据需要增长。
在其他语言中,整数的大小有限制,left + right
可能会溢出,而替代计算则不会。
在Python中,两者都不是更好。或者更确切地说,(left + right) // 2
稍微好一点,因为它少了一次算术运算。但这可以忽略不计。
在其他语言中,left + (right - left) // 2
用于避免 integer overflow,这可能在执行 left + right
时发生。这在 Python 中不会发生,因为 Python 本身允许任意大的整数;所以你看到的建议与 Python.
无关
这样做是为了处理C、C++等语言中数字和的溢出。您对整数范围有限制。在
int mid = (low+high)/2;
我们先求和再除法,对于大的low和high值可能会溢出缓冲区。
这种溢出情况的处理方法是先计算差值,然后除以差值并加上低位。结果是,
int mid = low + (high-low)/2;
在二分查找 while 循环中:
left, right = 0, len(nums)
while left < right:
mid = (left + right) // 2
if nums[mid] == target:
return mid
为什么在 python 以外的某些语言中 mid = (left + (right - left)) // 2
比 mid = (left + right) // 2
更好?
编辑:好像我把括号弄错了。感谢您指出这一点,它对我来说更清楚了。我会这样离开,以防其他人偶然发现这一点。我在 youtube 视频中看到了这个评论,但是那个人从来没有解释为什么一个会比另一个更好。谢谢大家的回答!
谢谢大家!
int
表示而言太高,left + right
可能会溢出。有关详细信息,请参阅 Extra, Extra - Read All About It: Nearly All Binary Searches and Mergesorts are Broken。
这是 C 等语言中的一个问题,其中 int
变量有限制,但 Python 中没有。使用更直接的代码应该没问题。
好吧,你把括号弄错了。我会让你弄明白的。
但是要回答你的问题:
在 Python 中没关系,因为整数可以根据需要增长。
在其他语言中,整数的大小有限制,left + right
可能会溢出,而替代计算则不会。
在Python中,两者都不是更好。或者更确切地说,(left + right) // 2
稍微好一点,因为它少了一次算术运算。但这可以忽略不计。
在其他语言中,left + (right - left) // 2
用于避免 integer overflow,这可能在执行 left + right
时发生。这在 Python 中不会发生,因为 Python 本身允许任意大的整数;所以你看到的建议与 Python.
这样做是为了处理C、C++等语言中数字和的溢出。您对整数范围有限制。在
int mid = (low+high)/2;
我们先求和再除法,对于大的low和high值可能会溢出缓冲区。
这种溢出情况的处理方法是先计算差值,然后除以差值并加上低位。结果是,
int mid = low + (high-low)/2;