LeetCopilot Logo
LeetCopilot
LeetCode Pattern/Binary Search/When Binary Search Is NOT O(log n): Hidden Complexity Traps

When Binary Search Is NOT O(log n): Hidden Complexity Traps

LeetCopilot Team
Dec 30, 2025
7 min read
Binary SearchTime ComplexityAlgorithm AnalysisInterview Prep
Binary search isn't always O(log n). Learn when feasibility checks, duplicates, or matrix searches change the complexity to O(n log m), O(n), or O(m+n).

"Binary search is O(log n)" is a common assumption. But it's not always true.

When you add a feasibility check, handle duplicates, or search in special structures, the complexity changes. Understanding these cases prevents wrong complexity analysis in interviews.

TL;DR

Binary search is NOT always O(log n):

  1. Binary search on answer: O(log(max-min) × feasibility_cost)
    • If feasibility is O(n), total is O(n log m)
  2. Rotated array with duplicates: O(n) worst case
  3. 2D matrix (staircase search): O(m + n)
  4. Finding all occurrences: O(log n + k) where k = count

Scenario 1: Binary Search on Answer with O(n) Check

The Hidden Cost

Problem: Koko Eating Bananas

Analysis:

code
Binary search iterations: O(log m) where m = max(piles)
Feasibility check per iteration: O(n) where n = len(piles)
Total: O(n log m)

Not O(log n)!

Example

python
def minEatingSpeed(piles, h):
    def can_finish(speed):
        hours = sum((pile + speed - 1) // speed for pile in piles)
        return hours <= h  # O(n) operation
    
    left, right = 1, max(piles)
    
    while left < right:  # O(log m) iterations
        mid = left + (right - left) // 2
        if can_finish(mid):  # O(n) per iteration
            right = mid
        else:
            left = mid + 1
    
    return left

# Time: O(n log m) where n = len(piles), m = max(piles)
# NOT O(log n)!

General Formula

Binary search on answer:

code
Time = O(log(answer_range) × feasibility_cost)

If feasibility is O(n): Total is O(n log m)
If feasibility is O(n²): Total is O(n² log m)

Scenario 2: Rotated Array with Duplicates

The Degradation

Problem: Search in Rotated Sorted Array II (with duplicates)

Analysis:

code
Best case: O(log n) — no ambiguity
Worst case: O(n) — must check almost all elements

Example

python
def search(nums, target):
    left, right = 0, len(nums) - 1
    
    while left <= right:
        mid = left + (right - left) // 2
        
        if nums[mid] == target:
            return True
        
        # When all three are equal, can't eliminate half
        if nums[left] == nums[mid] == nums[right]:
            left += 1  # O(1) progress
            right -= 1  # O(1) progress
        elif nums[left] <= nums[mid]:
            if nums[left] <= target < nums[mid]:
                right = mid - 1
            else:
                left = mid + 1
        else:
            if nums[mid] < target <= nums[right]:
                left = mid + 1
            else:
                right = mid - 1
    
    return False

# Worst case: [1, 1, 1, 1, 1, 1, 1, 0, 1]
# Almost all elements are 1, must check most of them
# Time: O(n) worst case

Why It Happens

code
Array: [2, 2, 2, 2, 2, 2, 2, 0, 2]

At almost every step:
  nums[left] == nums[mid] == nums[right] = 2
  Can't determine which half is sorted
  Must shrink by 1 element at a time
  
Result: O(n) time

The Linear Complexity

Problem: Search a 2D Matrix II (row-column sorted)

Analysis:

code
Start from top-right (or bottom-left)
Each step eliminates one row or one column
Worst case: eliminate all rows + all columns
Time: O(m + n)

Example

python
def searchMatrix(matrix, target):
    if not matrix or not matrix[0]:
        return False
    
    rows, cols = len(matrix), len(matrix[0])
    row, col = 0, cols - 1  # Start from top-right
    
    while row < rows and col >= 0:
        if matrix[row][col] == target:
            return True
        elif matrix[row][col] > target:
            col -= 1  # Eliminate column
        else:
            row += 1  # Eliminate row
    
    return False

# Time: O(m + n) where m = rows, n = cols
# NOT O(log(m × n))!

Why Not O(log n)?

code
Matrix is NOT fully sorted:
[1,  4,  7, 11]
[2,  5,  8, 12]
[3,  6,  9, 16]
[10, 13, 14, 17]

Can't treat as 1D sorted array
Must use staircase search: O(m + n)

Scenario 4: Finding All Occurrences

The Output-Sensitive Complexity

Problem: Find all indices of target

Analysis:

code
Find first occurrence: O(log n)
Find last occurrence: O(log n)
Return all indices: O(k) where k = count
Total: O(log n + k)

Example

python
def findAllOccurrences(nums, target):
    # Find first occurrence: O(log n)
    first = lower_bound(nums, target)
    
    if first == len(nums) or nums[first] != target:
        return []
    
    # Find last occurrence: O(log n)
    last = upper_bound(nums, target) - 1
    
    # Return all indices: O(k)
    return list(range(first, last + 1))

# Time: O(log n + k) where k = number of occurrences
# If k = n (all elements are target), time is O(n)

Scenario 5: Binary Search with Expensive Comparison

The Comparison Cost

Problem: Binary search on strings

Analysis:

code
Binary search iterations: O(log n)
String comparison per iteration: O(L) where L = string length
Total: O(L log n)

Example

python
def binarySearchStrings(strings, target):
    left, right = 0, len(strings) - 1
    
    while left <= right:
        mid = left + (right - left) // 2
        
        # String comparison is O(L)
        if strings[mid] == target:
            return mid
        elif strings[mid] < target:
            left = mid + 1
        else:
            right = mid - 1
    
    return -1

# Time: O(L log n) where L = average string length
# NOT O(log n)!

Complexity Summary Table

ScenarioComplexityReason
Classic binary searchO(log n)Standard
Binary search on answerO(log m × C)C = feasibility cost
Koko Eating BananasO(n log m)Feasibility is O(n)
Rotated with duplicatesO(n) worstMust check all elements
2D staircase searchO(m + n)Eliminate row or column
Find all occurrencesO(log n + k)k = count
String binary searchO(L log n)L = string length

How to Calculate True Complexity

Step 1: Identify the Binary Search Component

code
How many iterations? O(log n) or O(log(max-min))?

Step 2: Identify the Per-Iteration Cost

code
What happens in each iteration?
- Simple comparison? O(1)
- Feasibility check? O(n), O(n²), etc.
- String comparison? O(L)

Step 3: Multiply

code
Total = iterations × per-iteration cost

Example: Split Array Largest Sum

python
def splitArray(nums, m):
    def can_split(max_sum):
        subarrays = 1
        current_sum = 0
        for num in nums:  # O(n)
            if current_sum + num > max_sum:
                subarrays += 1
                current_sum = num
            else:
                current_sum += num
        return subarrays <= m
    
    left, right = max(nums), sum(nums)
    
    while left < right:  # O(log(sum - max))
        mid = left + (right - left) // 2
        if can_split(mid):  # O(n)
            right = mid
        else:
            left = mid + 1
    
    return left

# Time: O(n log(sum - max))
# NOT O(log n)!

Common Misconceptions

Misconception 1: "Binary search is always O(log n)"

False. Depends on what you're searching and what operations you do per iteration.

Misconception 2: "Binary search on answer is O(log n)"

False. It's O(log(answer_range) × feasibility_cost).

Misconception 3: "All 2D matrix searches are O(log(m×n))"

False. Only fully sorted matrices. Row-column sorted is O(m+n).

FAQ

Q: Is binary search still worth it if it's not O(log n)?

A: Yes! O(n log m) is still better than O(n²) brute force.

Q: How do I know the true complexity?

A: Analyze: iterations × per-iteration cost.

Q: Can I optimize the feasibility check?

A: Sometimes, but often it's inherently O(n). That's ok.

Q: Should I mention this in interviews?

A: Yes! Saying "O(n log m)" shows deeper understanding than "O(log n)".

Conclusion

Binary search isn't always O(log n). The true complexity depends on:

  1. What you're searching: Answer space, array, matrix
  2. Per-iteration cost: Feasibility check, comparison cost
  3. Special cases: Duplicates, output size

Key scenarios:

  • Binary search on answer: O(log m × feasibility_cost)
  • Rotated with duplicates: O(n) worst case
  • 2D staircase: O(m + n)
  • Find all: O(log n + k)

How to analyze:

  1. Count iterations
  2. Measure per-iteration cost
  3. Multiply

Understanding these nuances shows interview depth and prevents wrong complexity claims. For more details, see Binary Search on Answer, Rotated Array Duplicates, and the Complete Binary Search Guide.

Want to Practice LeetCode Smarter?

LeetCopilot is a free browser extension that enhances your LeetCode practice with AI-powered hints, personalized study notes, and realistic mock interviews — all designed to accelerate your coding interview preparation.

Also compatible with Edge, Brave, and Opera

Related Tutorials