There are several problems in your code:
mid = abs(end - start) / 2
This is not the middle between start and end , it is half the distance between them (rounded to the nearest whole). Later you use it as if it is really a valid index:
findBestIndex(target, start, mid - 1)
It is not so. You probably wanted to use mid = (start + end) // 2 or something here. You will also skip a few indexes because you skip the middle:
return findBestIndex(target, start, mid - 1) ... return findBestIndex(target, mid + 1, end)
Now your base case should be expressed a little differently. A good candidate is the condition
if start == end
Because now you know for sure that youβve finished the search. Note that you should also consider the case where all elements of the array are less than target , so you need to insert it at the end.
I do not often look for a binary file, but if so, how
Binary search is something that is surprisingly hard to understand if you have never done it before. I usually use the following pattern if I do a binary search:
lo, hi = 0, n
Provided that check is a monotone binary predicate (it is always false to some point and true from this point), after this loop lo == hi will be the first number in the range [0..n] with check(lo) == true . check(n) implies that it is true (this is part of the magic of this approach).
So, what is a monotone predicate that is true for all indices, including after our target position, and false for all positions before?
If we think about it, we want to find the first number in the array that is larger than our goal, so we just plug it in and we are good to go:
lo, hi = 0, n while lo < hi: mid = (lo + hi) // 2 if (a[mid] > target): hi = mid else: lo = mid + 1 return lo;