Binary Search is famous for being "easy to explain, hard to implement correctly." Off-by-one errors and infinite loops are the two most common failure modes. Interviewers specifically watch for these bugs.
The Standard Template
Memorize this structure. Every variation of Binary Search — finding the first occurrence, the last occurrence, the insertion point — is a modification of this skeleton:
def binary_search(arr, target):
left, right = 0, len(arr) - 1
while left <= right: # (1) Loop condition
mid = left + (right - left) // 2 # (2) Mid calculation
if arr[mid] == target:
return mid # Found it
elif arr[mid] < target:
left = mid + 1 # (3) Move strictly past mid
else:
right = mid - 1 # (3) Move strictly past mid
return -1 # Target not found
Why each line matters:
-
while left <= right— The<=(not<) is critical. Without it, you miss the case whereleft == right, which is a valid single-element search space. Using<causes you to skip the last remaining candidate. -
mid = left + (right - left) // 2— This is mathematically equivalent to(left + right) // 2, but avoids integer overflow. In Python this doesn't matter (integers are unbounded), but in C++ and Java,left + rightcan overflow a 32-bit integer when both values are large. Writing it this way is a habit that signals senior-level awareness. -
left = mid + 1andright = mid - 1— You move the pointer pastmid, not tomid. If you writeleft = mid, andarr[mid]is not the target,leftnever advances and you loop forever.
Common Variations
| Goal | Modification |
|---|---|
| Find first occurrence of target | When arr[mid] == target, set right = mid - 1 and record mid |
| Find last occurrence of target | When arr[mid] == target, set left = mid + 1 and record mid |
| Find insertion point | Return left when the loop ends |
Interviewers frequently ask: "What's the difference between while left < right and while left <= right?" The answer: left <= right handles the case where the search space narrows to exactly one element — that element still needs to be checked. Using left < right exits the loop one step too early and misses it. Always use <= in the standard template unless you have a specific reason not to.