Binary Search as Divide and Conquer in DSA Python - Time & Space Complexity
We want to understand how the time taken by binary search changes as the list size grows.
How many steps does it take to find an item when we keep splitting the list?
Analyze the time complexity of the following code snippet.
def binary_search(arr, target):
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
This code searches for a target value in a sorted list by repeatedly dividing the search range in half.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Checking the middle element of the current search range.
- How many times: The search range halves each time, so this check repeats about log₂(n) times.
Each step cuts the list size in half, so the number of steps grows slowly as the list gets bigger.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 4 checks |
| 100 | About 7 checks |
| 1000 | About 10 checks |
Pattern observation: Doubling the input size adds only one extra step.
Time Complexity: O(log n)
This means the number of steps grows slowly, making binary search very efficient for large lists.
[X] Wrong: "Binary search checks every element one by one like linear search."
[OK] Correct: Binary search skips half the list each time, so it does far fewer checks than linear search.
Understanding binary search's time complexity shows you can analyze efficient algorithms that use divide and conquer, a key skill in many coding challenges.
"What if the list was not sorted? How would the time complexity of searching change?"
Practice
Binary Search as a divide and conquer algorithm?Solution
Step 1: Understand divide and conquer in binary search
Binary search splits the sorted list into two halves and decides which half to search next.Step 2: How binary search reduces search space
By halving the search range each time, it quickly narrows down where the target could be.Final Answer:
It divides the search range in half each time to find the target efficiently. -> Option CQuick Check:
Divide and conquer = halve search space [OK]
- Thinking binary search checks every element
- Assuming binary search works on unsorted lists
- Confusing binary search with linear search
arr with indices low and high?Solution
Step 1: Understand integer division for index calculation
We need an integer index, so floor division (//) is used to get the middle index.Step 2: Check each option for correctness
mid = (low + high) // 2 uses floor division correctly. mid = (low + high) / 2 uses float division, which is invalid for indexing. Options C and D do not calculate the middle index properly.Final Answer:
mid = (low + high) // 2 -> Option AQuick Check:
Use floor division for middle index [OK]
- Using / which gives float index
- Adding indices without dividing
- Incorrect operator precedence
def binary_search(arr, target):
low, high = 0, len(arr) - 1
while low <= high:
mid = (low + high) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
low = mid + 1
else:
high = mid - 1
return -1
arr = [2, 4, 6, 8, 10]
print(binary_search(arr, 6))Solution
Step 1: Trace the binary search for target 6
Initial low=0, high=4, mid=2. arr[2]=6 matches target, so return 2.Step 2: Confirm returned index
The function returns index 2 where 6 is found.Final Answer:
2 -> Option DQuick Check:
Target found at index 2 [OK]
- Confusing index with value
- Off-by-one errors in mid calculation
- Returning -1 incorrectly
def binary_search(arr, target):
low, high = 0, len(arr)
while low <= high:
mid = (low + high) // 2
if arr[mid] == target:
return mid
elif arr[mid] < target:
low = mid + 1
else:
high = mid - 1
return -1Solution
Step 1: Check initialization of high index
Using 'high = len(arr)' causes out-of-range error because last valid index is len(arr) - 1.Step 2: Correct high initialization
Set 'high = len(arr) - 1' to ensure mid index stays within valid range.Final Answer:
Change 'high = len(arr)' to 'high = len(arr) - 1' to avoid index error. -> Option AQuick Check:
High index must be last valid index [OK]
- Setting high to length causes index error
- Changing loop condition incorrectly
- Miscalculating mid index
arr = [1, 3, 5, 7, 9, 11, 13], you want to find the smallest index where the value is greater than or equal to 8 using binary search. Which modification to the standard binary search will achieve this?Solution
Step 1: Understand the problem - find smallest index with value >= 8
This is a variant called lower bound search, requiring careful adjustment of pointers.Step 2: Modify binary search to narrow down to smallest qualifying index
When arr[mid] >= 8, move 'high' to mid - 1 to check if smaller index also qualifies; else move 'low' to mid + 1.Final Answer:
Adjust binary search to move 'high' to mid - 1 when arr[mid] >= 8, else move 'low' to mid + 1. -> Option BQuick Check:
Lower bound search moves high left on >= condition [OK]
- Returning immediately without checking smaller indices
- Using linear search unnecessarily
- Moving low pointer incorrectly
Ready to prove it?
Pass the test and this pattern moves unknown
