Find Peak Element in Python Using Binary Search

A binary search solution that finds any peak element (an element strictly greater than its neighbors) in an unsorted array in O(log n) time.

Medium Python 3.9+ Aug 9, 2026 Algorithms & data structures 18 views 0 copies

Python code

21 lines
Python 3.9+
def find_peak_element(nums):
    left, right = 0, len(nums) - 1
    
    while left < right:
        mid = (left + right) // 2
        if nums[mid] > nums[mid + 1]:
            right = mid
        else:
            left = mid + 1
            
    return left

if __name__ == "__main__":
    test1 = [1, 2, 3, 1]
    test2 = [1, 2, 1, 3, 5, 6, 4]
    test3 = [1, 2, 3]
    test4 = [3, 2, 1]
    
    for i, arr in enumerate([test1, test2, test3, test4], 1):
        peak_idx = find_peak_element(arr)
        print(f"Test {i}: {arr} -> peak at index {peak_idx} (value {arr[peak_idx]})")

Output

stdout
Test 1: [1, 2, 3, 1] -> peak at index 2 (value 3)
Test 2: [1, 2, 1, 3, 5, 6, 4] -> peak at index 5 (value 6)
Test 3: [1, 2, 3] -> peak at index 2 (value 3)
Test 4: [3, 2, 1] -> peak at index 0 (value 3)

How it works

The algorithm leverages the fact that if nums[mid] < nums[mid + 1], a peak must exist on the right side (since the sequence is increasing at that point). Conversely, if nums[mid] > nums[mid + 1], a peak must exist on the left side or at mid itself. By halving the search space each iteration, we achieve logarithmic time complexity. The loop terminates when left == right, which is guaranteed to be a peak index because the array constraints ensure at least one peak exists (using -∞ as implicit neighbors at boundaries).

Common mistakes

  • Returning the value instead of the index of the peak element
  • Using `left <= right` which causes infinite loops in this pattern
  • Forgetting that edge elements only need to be greater than their single neighbor
  • Assuming the array is sorted when it's actually arbitrary

Variations

  1. Return the peak value instead of the index by using `return nums[left]`
  2. Use the `bisect` module with a custom comparator for more complex peak definitions

Real-world use cases

  • Finding a local maxima in a time-series dataset to detect a revenue spike or anomaly.
  • Locating a peak in audio signal processing to identify the loudest frequency component.
  • Optimizing a function's parameter search where a peak indicates the best configuration.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Algorithms & data structures

Related tutorials and quizzes for this topic.