选择的答案不是最优的。如果您试图最小化探针的数量(数组查找),您可以做得比从头开始搜索和采取的步骤小到`target - array[i]
由于您可以使用索引查找进行随机访问,因此您可以取得更大的进步。例如,如果您在以 开头的数组中查找9a[0] = 0
,您可以检查a[16]
它是否小于或等于0。如果没有,那么没有一个a[0 .. 16]
可以达到9。
更大的步幅为您提供每个探针的更多信息(每个探针都可以让您排除左侧和右侧的指标)。与从左侧搜索时的最小步幅相比,这可以让您在每次探测时获得两倍的信息。
为了展示从中间搜索比从左搜索的优势,这里有一些用 Python 编程语言编写的工作代码:
def find(arr, value, bias=2):
# With the bias at 2, new probes are in the middle of the range.
# Increase the bias to force the search leftwards.
# A very large bias does the same as searching from left side of the range.
todo = [(0, len(arr)-1)] # list of ranges where the value is possible
while todo:
low, high = todo.pop()
if low == high:
if arr[low] == value: return low
else: continue
mid = low + (high - low) // bias
diff = abs(arr[mid] - value)
if mid+diff <= high: todo.append([mid + diff, high])
if mid-diff >= low: todo.append([low, mid - diff])
raise ValueError('Value is not in the array')
从概念上讲,该算法正在做的是尝试通过每个探针获得尽可能多的信息。有时,它会很幸运并一次排除大范围;有时,它会很不幸,只能排除一个很小的子范围。不管运气如何,它的禁区将是从左搜索方法的两倍。
简单的测试代码:
arr = [10, 11, 12, 13, 14, 13, 12, 11, 10, 9, 8, 7, 6, 7, 8]
for i in range(min(arr), max(arr)+1):
assert arr.index(i) == find(arr, i)