Find Any Local Maximum in an Array
Solve this Problemnums where adjacent elements are never equal, return the index of any peak.
Aim for O(log n) time. Comparing nums[mid] with nums[mid + 1] tells you which direction climbs toward higher ground — follow it, and you're guaranteed to reach a peak.
Test Case 1:
Test Case 2:
Test Case 3:
Constraints
- ◆
1 ≤ nums.length ≤ 1000 - ◆
-2³¹ ≤ nums[i] ≤ 2³¹ - 1 - ◆
nums[i] ≠ nums[i + 1] for every valid i - ◆
If multiple peaks exist, returning the index of any one of them is accepted
Try the Dry Run
Don't just read the solution — watch it execute, one step at a time.
| 1 | class Solution { |
| 2 | public int findPeakElement(int[] nums) { |
| 3 | int lo = 0, hi = nums.length - 1; |
| 4 | while (lo < hi) { |
| 5 | int mid = lo + (hi - lo) / 2; |
| 6 | if (nums[mid] < nums[mid + 1]) { |
| 7 | lo = mid + 1; |
| 8 | } else { |
| 9 | hi = mid; |
| 10 | } |
| 11 | } |
| 12 | return lo; |
| 13 | } |
| 14 | } |
| 15 |
06Search [0, 6] for any index where the value is greater than both neighbors — climb toward higher ground.
Approach & Solutions
Brute Force — Linear Scan
BruteCheck every index and confirm both of its neighbors (treating the array's edges as negative infinity) are smaller. The first index that qualifies is a peak. It's correct, but it never uses the fact that you can tell which direction climbs toward a peak just by comparing two adjacent values.
O(n)O(1)1class Solution {
2 public int findPeakElement(int[] nums) {
3 for (int i = 0; i < nums.length; i++) {
4 boolean leftOk = (i == 0) || nums[i - 1] < nums[i];
5 boolean rightOk = (i == nums.length - 1) || nums[i] > nums[i + 1];
6 if (leftOk && rightOk) return i;
7 }
8 return -1;
9 }
10}Optimal — Binary Search
OptimalCompare nums[mid] with its right neighbor. If nums[mid] < nums[mid + 1], the slope is still climbing, so a peak is guaranteed to exist somewhere to the right (the array can't climb forever) — search right. Otherwise the slope is falling (or mid is itself a local max), so a peak exists at mid or to its left — keep mid in range and search left.
O(log n)O(1)1class Solution {
2 public int findPeakElement(int[] nums) {
3 int lo = 0, hi = nums.length - 1;
4 while (lo < hi) {
5 int mid = lo + (hi - lo) / 2;
6 if (nums[mid] < nums[mid + 1]) {
7 lo = mid + 1;
8 } else {
9 hi = mid;
10 }
11 }
12 return lo;
13 }
14}