【发布时间】:2020-11-16 07:23:08
【问题描述】:
在对答案执行二分搜索时,我看到了以下不同形式:
loop condition : (low+1<hi), (low<hi), (low<=hi) updating indices: (hi=mid+1), (hi=mid), (low=mid), (low=mid-1)
这些有什么区别,它们真的重要吗?
【问题讨论】:
标签: c++ algorithm binary-search
在对答案执行二分搜索时,我看到了以下不同形式:
loop condition : (low+1<hi), (low<hi), (low<=hi) updating indices: (hi=mid+1), (hi=mid), (low=mid), (low=mid-1)
这些有什么区别,它们真的重要吗?
【问题讨论】:
标签: c++ algorithm binary-search
每个循环条件都简单地说明循环何时结束。如果您想准确找到一个元素,lo < hi 通常是最简单的方法。对于两个元素,或者可以使用lo + 1 < hi。 lo <= hi 通常与 while 循环中的早期返回语句配对。
在更新索引之前,通常选择mid 或(lo + hi) / 2 或(lo + hi + 1) / 2(忽略整数溢出)。它们之间的区别在于,如果lo 和hi 之间存在偶数个元素,则第一个偏向lo,而第二个偏向hi。
更新索引附有+ 1 以确保没有无限循环。通常,您要确保在循环的每次迭代中,lo 和 hi 至少被修改 1。
作为参考,这是我首选的二分搜索方式:
int binary_search(std::vector<int> nums, int target) {
if (nums.empty())
return -1;
int l = 0;
int h = nums.size() - 1;
while (l < h) {
// If the language doesn't have big ints, make sure there is no overflow.
// This has a left bias if there are an even number of elements left.
int m = l + (h - l) / 2;
if (nums[m] < target) {
// The `+ 1` here is important. Without this, if there are two elements
// and nums[0] < target, we'll get an infinite loop.
l = m + 1;
} else {
// Since `m < h`, we "make progress" in this case.
h = m;
}
}
return nums[l] == target ? l : -1;
}
我喜欢这种方法,因为很明显没有死循环,退出条件也不依赖提前返回语句。
【讨论】: