因此,我从概念上了解二进制搜索的工作原理,但是在尝试在数组中查找索引时,在实现它方面总是遇到问题。例如,对于LC的“搜索插入位置”,这是我写的:
def searchInsert(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: int
"""
if target > nums[-1]:
return len(nums)
low = 0
high = len(nums) - 1
while high > low:
mid = (low + high) // 2
if nums[mid] == target:
return mid
elif nums[mid] > target:
high = mid
else:
low = mid + 1
return low
它可以工作,但是我不明白为什么我必须将低更新为中+ 1,而不是将低更新为中。同样,为什么我将中点更新为中点而不是中点-1。我尝试更新中点/中间点,因为中点,中点-1和中点+ 1的每种组合都适用,而以上是唯一可行的方法,但我没有知道为什么。
对这些类型的问题实施二进制搜索时,是否有办法推理出如何更新低/高值?
答案 0 :(得分:1)
这是个人喜好:
while high >= low:
mid = (low + high) // 2
if nums[mid] >= target:
high = mid - 1
else:
low = mid + 1
return low
# or return nums[low] == target for boolean
在具有相同值的情况下具有区别。
例如,假设数组为[1,1,2,2,3,3,3,3,4]
。
使用您的函数,search(arr, 1)
返回了1
,但search(arr, 2)
返回了2
。
为什么它在间隔1
s返回最右索引,而在2
s返回最左索引?
我认为,密钥位于if nums[mid] >= target:
。
当它找到完全相同的目标时,范围将以high = mid - 1
改变。这意味着high
可能不是答案,因为我们找到的答案是mid
。 [1]
在二分查找的最后一步,范围将接近零。最终他们越过循环中断。因此,答案必须为low
或high
。但是我们知道high
并不是[1]的答案。