Transition Point Recipe Overview and Analysis
The transition point recipe is a universal pattern that works for all binary search problems. Understanding this recipe eliminates confusion about which template to use.
The Core Pattern
Binary search finds a transition point where a property changes from False to True (or vice versa).
[False, False, False, True, True, True]
↑
Transition Point
The Three Templates
Template 1: Classic Binary Search
Use when: Finding exact value or simple condition.
def binary_search_template_1(nums, target):
left, right = 0, len(nums) - 1
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
Key points:
- Loop while
left <= right - Can return mid immediately when found
- After loop, left > right (no elements left)
Template 2: Find Boundary (Left-most/Right-most)
Use when: Finding first/last occurrence, insertion point, or boundaries.
def binary_search_template_2(nums, target):
"""Find leftmost (smallest) index where condition is true"""
left, right = 0, len(nums)
while left < right:
mid = left + (right - left) // 2
if nums[mid] < target:
left = mid + 1
else:
right = mid
# left is the leftmost position where nums[left] >= target
return left
Key points:
- Loop while
left < right(not<=) - Never return mid in loop
right = mid(not mid - 1)- After loop, left == right
Template 3: Find with Neighbors
Use when: Need to check mid's neighbors.
def binary_search_template_3(nums, target):
"""Need to check mid-1 and mid+1"""
if len(nums) == 0:
return -1
left, right = 0, len(nums) - 1
while left + 1 < right:
mid = left + (right - left) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid
else:
right = mid
# Check remaining elements
if nums[left] == target:
return left
if nums[right] == target:
return right
return -1
Key points:
- Loop while
left + 1 < right(leaves 2 elements) left = midandright = mid(not +/- 1)- Check both left and right after loop
Choosing the Right Template
Need to return immediately when found?
├─ Yes → Template 1
│
└─ No → Finding boundary/insertion point?
├─ Yes → Template 2
│
└─ No → Need to check neighbors?
└─ Yes → Template 3
Transition Point Analysis
The key insight: Every binary search problem is about finding a transition point.
- Template 1: Transition from "not found" to "found"
- Template 2: Transition from "condition false" to "condition true"
- Template 3: Transition point requires neighbor context
Common Patterns
Pattern 1: Exact Match
while left <= right:
mid = left + (right - left) // 2
if nums[mid] == target:
return mid
elif nums[mid] < target:
left = mid + 1
else:
right = mid - 1
Pattern 2: Find Leftmost
while left < right:
mid = left + (right - left) // 2
if nums[mid] < target:
left = mid + 1
else:
right = mid
Pattern 3: Find Rightmost
while left < right:
mid = left + (right - left) // 2
if nums[mid] <= target:
left = mid + 1
else:
right = mid
left -= 1 # Adjust to last occurrence
Key Takeaway
Master these three templates and you can solve any binary search problem. The transition point recipe helps you identify which template to use based on what you're searching for.