这是一个略有不同的版本
def search(nums, target):
low = 0
high = len(nums)-1
while low <= high:
mid = (low + high) // 2
l = nums[low]
m = nums[mid]
h = nums[high]
if target == l:
return low
if target == m:
return mid
if target == h:
return high
if any([
l < m < h and target < m,
l == m < h and target > m,
l > m < h and target > l and target > m,
l > m < h and target < l and target < m,
l < m > h and target > l and target < m
]):
high = mid
elif any([
l < m < h and target > m,
l > m < h and target > m and target < h,
l < m > h,
]):
low = mid
elif target < l or target > h:
break
elif l == m == h:
break
else:
raise Exception("This is not possible, only if some values are reverse/unordered!")
return -1
用这个数据测试过(第一列是目标,第二列是列表,第三列是结果索引):
-10 [1] -1
1 [1] 0
22 [1] -1
-10 [1, 2] -1
1 [1, 2] 0
2 [1, 2] 1
22 [1, 2] -1
-10 [2, 1] -1
1 [2, 1] 1
2 [2, 1] 0
22 [2, 1] -1
-10 [1, 5] -1
1 [1, 5] 0
5 [1, 5] 1
22 [1, 5] -1
-10 [5, 1] -1
1 [5, 1] 1
5 [5, 1] 0
22 [5, 1] -1
-10 [1, 2, 3] -1
1 [1, 2, 3] 0
2 [1, 2, 3] 1
3 [1, 2, 3] 2
22 [1, 2, 3] -1
-10 [3, 1, 2] -1
1 [3, 1, 2] 1
2 [3, 1, 2] 2
3 [3, 1, 2] 0
22 [3, 1, 2] -1
-10 [2, 3, 1] -1
1 [2, 3, 1] 2
2 [2, 3, 1] 0
3 [2, 3, 1] 1
22 [2, 3, 1] -1
-10 [1, 5, 10] -1
1 [1, 5, 10] 0
5 [1, 5, 10] 1
2 [1, 5, 10] -1
10 [1, 5, 10] 2
22 [1, 5, 10] -1
-10 [10, 1, 5] -1
1 [10, 1, 5] 1
5 [10, 1, 5] 2
2 [1, 5, 10] -1
10 [10, 1, 5] 0
22 [10, 1, 5] -1
-10 [5, 10, 1] -1
1 [5, 10, 1] 2
5 [5, 10, 1] 0
2 [1, 5, 10] -1
10 [5, 10, 1] 1
22 [5, 10, 1] -1
-10 [1, 2, 3, 4] -1
1 [1, 2, 3, 4] 0
2 [1, 2, 3, 4] 1
3 [1, 2, 3, 4] 2
4 [1, 2, 3, 4] 3
-10 [1, 2, 3, 4] -1
-10 [4, 1, 2, 3] -1
1 [4, 1, 2, 3] 1
2 [4, 1, 2, 3] 2
3 [4, 1, 2, 3] 3
4 [4, 1, 2, 3] 0
-10 [4, 1, 2, 3] -1
-10 [3, 4, 1, 2] -1
1 [3, 4, 1, 2] 2
2 [3, 4, 1, 2] 3
3 [3, 4, 1, 2] 0
4 [3, 4, 1, 2] 1
-10 [3, 4, 1, 2] -1
-10 [2, 3, 4, 1] -1
1 [2, 3, 4, 1] 3
2 [2, 3, 4, 1] 0
3 [2, 3, 4, 1] 1
4 [2, 3, 4, 1] 2
-10 [2, 3, 4, 1] -1
-10 [1, 5, 8, 22] -1
1 [1, 5, 8, 22] 0
5 [1, 5, 8, 22] 1
8 [1, 5, 8, 22] 2
22 [1, 5, 8, 22] 3
10 [1, 5, 8, 22] -1
100 [1, 5, 8, 22] -1
-10 [22, 1, 5, 8] -1
1 [22, 1, 5, 8] 1
5 [22, 1, 5, 8] 2
8 [22, 1, 5, 8] 3
22 [22, 1, 5, 8] 0
10 [22, 1, 5, 8] -1
100 [22, 1, 5, 8] -1
-10 [8, 22, 1, 5] -1
1 [8, 22, 1, 5] 2
5 [8, 22, 1, 5] 3
8 [8, 22, 1, 5] 0
22 [8, 22, 1, 5] 1
10 [8, 22, 1, 5] -1
100 [8, 22, 1, 5] -1
-10 [5, 8, 22, 1] -1
1 [5, 8, 22, 1] 3
5 [5, 8, 22, 1] 0
8 [5, 8, 22, 1] 1
22 [5, 8, 22, 1] 2
10 [5, 8, 22, 1] -1
100 [5, 8, 22, 1] -1
5 [5, 1, 2, 3, 4] 0
1 [5, 1, 2, 3, 4] 1
2 [5, 1, 2, 3, 4] 2
3 [5, 1, 2, 3, 4] 3
4 [5, 1, 2, 3, 4] 4
5 [4, 5, 1, 2, 3] 1
1 [4, 5, 1, 2, 3] 2
2 [4, 5, 1, 2, 3] 3
3 [4, 5, 1, 2, 3] 4
4 [4, 5, 1, 2, 3] 0
5 [3, 4, 5, 1, 2] 2
1 [3, 4, 5, 1, 2] 3
2 [3, 4, 5, 1, 2] 4
3 [3, 4, 5, 1, 2] 0
4 [3, 4, 5, 1, 2] 1
5 [2, 3, 4, 5, 1] 3
1 [2, 3, 4, 5, 1] 4
2 [2, 3, 4, 5, 1] 0
3 [2, 3, 4, 5, 1] 1
4 [2, 3, 4, 5, 1] 2
5 [5, 77, 1, 2, 3] 0
77 [5, 77, 1, 2, 3] 1
1 [5, 77, 1, 2, 3] 2
2 [5, 77, 1, 2, 3] 3
3 [5, 77, 1, 2, 3] 4
5 [5, 6, 1, 2, 3] 0
6 [5, 6, 1, 2, 3] 1
1 [5, 6, 1, 2, 3] 2
2 [5, 6, 1, 2, 3] 3
3 [5, 6, 1, 2, 3] 4
5 [5, 6, 1, 2, 3, 4] 0
6 [5, 6, 1, 2, 3, 4] 1
1 [5, 6, 1, 2, 3, 4] 2
2 [5, 6, 1, 2, 3, 4] 3
3 [5, 6, 1, 2, 3, 4] 4
4 [5, 6, 1, 2, 3, 4] 5
之所以不是O(n)是因为在O(n)的情况下这意味着算法的性能将随着数据的增加而线性下降,而在这种情况下,随着输入数据的增加,性能以对数方式下降,因为对于每次迭代,我们将数据集拆分为更小和更小。