Find peak element


A peak element is an element that is strictly greater than its neighbors.

Given a 0-indexed integer array nums, find a peak element, and return its index. If the array contains multiple peaks, return the index to any of the peaks.

You may imagine that nums[-1] = nums[n] = -∞. In other words, an element is always considered to be strictly greater than a neighbor that is outside the array.

You must write an algorithm that runs in O(log n) time.

Example 1:

Input: nums = [1,2,3,1]
Output: 2
Explanation: 3 is a peak element and your function should return the index number 2.

Here’s a Java implementation of the O(log n) binary‐search approach, followed by a detailed walkthrough of the algorithm.

class Solution {
    /**
     * Finds any peak element’s index in the array.
     * A peak is an element strictly greater than its neighbors.
     *
     * @param nums input array where nums[i] != nums[i+1]
     * @return index of a peak element
     */
    public int findPeakElement(int[] nums) {
        int lo = 0;
        int hi = nums.length - 1;

        // Continue until the search window narrows to one element
        while (lo < hi) {
            int mid = lo + (hi - lo) / 2;
            
            // If the mid element is less than its right neighbor,
            // then a peak must lie to the right of mid.
            if (nums[mid] < nums[mid + 1]) {
                lo = mid + 1;
            } else {
                // Otherwise, a peak is at mid or to the left of mid.
                hi = mid;
            }
        }

        // lo == hi is the index of a peak element
        return lo;
    }
}


Algorithm Explanation

  1. Problem Restatement
    We need to find any index i such that nums[i] > nums[i - 1] and nums[i] > nums[i + 1] (with the convention that out-of-bounds neighbors are treated as -∞, so endpoints can also be peaks).
  2. Why Binary Search Works
    • If at position mid, nums[mid] < nums[mid+1], you are on an ascending slope. A peak must exist somewhere to the right (because eventually you must descend to -∞ at the far end).
    • Otherwise (nums[mid] > nums[mid+1]), you are on a descending slope or at a local peak. A peak exists at mid or to the left.
  3. Step-by-Step
    • Initialize two pointers, lo = 0 and hi = n-1.
    • Loop while lo < hi:
      1. Compute mid = lo + (hi - lo) / 2 to avoid overflow.
      2. Comparenums[mid] and nums[mid+1].
        • If nums[mid] < nums[mid+1], shift right: lo = mid + 1.
        • Else, shift left: hi = mid.
    • Terminate when lo == hi. This index is guaranteed to be a peak.
  4. Time & Space Complexity
    • Time: O(log n) — we halve the search interval each step.
    • Space: O(1) — only a few integer pointers.
  5. Edge Cases
    • Length 1: immediately returns 0 (the single element is a peak).
    • Monotonic arrays (strictly increasing or decreasing):
      • Increasing ⇒ peak at rightmost index.
      • Decreasing ⇒ peak at leftmost index.

This method finds a valid peak in logarithmic time and constant extra space.


Leave a comment