Чтобы повторить то, что я сказал в своем комментарии, проблема в том, что вы теряете след a
.
Ваш подход рекурсивный, и вы передаете список с уменьшающимся размером при каждом вызове.Из-за этого середина, которую вы ищете, и середина, которую вы в конечном итоге сравниваете, не одинаковы.
Переключитесь на итеративный подход, и вы можете держать вещи в контексте оригинального a
.
def fixed_point(a):
l, u = 0, len(a)
while l <= u:
m = (l + u) // 2
if m == a[m]:
return m
elif m > a[m]:
l = m + 1
else:
u = m - 1
return -1
>>> fixed_point([-10, -5, -2, 2, 3, 5, 7, 10, 15, 25, 35, 78, 129])
5
Преимущество итерации также заключается в меньших накладных расходах памяти (нет необходимости в стеках вызовов), хотя на других языках некоторые компиляторы оптимизируют.