A peak element is an element that is greater than its neighbors.
Given an input array nums, where nums[i] ≠ nums[i+1], find a peak element and return its index.
The array may contain multiple peaks, in that case return the index to any one of the peaks is fine.
You may imagine that nums[-1] = nums[n] = -∞.
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.
Example 2:
Input: nums = [1, 2, 1, 3, 5, 6, 4]
Output: 1 or 5
Explanation: Your function can return either index number 1 where the peak element is 2,
or index number 5 where the peak element is 6.
Your algorithm should run in O(log n) time and use O(1) extra space.
The core challenge of this problem is to find an element in the array that is greater than its neighbors. This is significant in various applications such as finding local maxima in signal processing or identifying peaks in data analysis. A common misconception is to think that the peak must be the global maximum, but any local peak is sufficient.
To solve this problem, we can use a binary search approach to achieve the required O(log n) time complexity. The naive solution would involve a linear scan of the array, which would take O(n) time. However, this is not optimal for large arrays.
The naive approach involves iterating through the array and checking each element to see if it is greater than its neighbors. This approach is straightforward but not efficient.
The optimized solution uses a binary search approach. The idea is to divide the array into two halves and determine which half contains a peak element. This is based on the observation that if the middle element is not a peak, then at least one of its neighbors must be greater, indicating that a peak must exist in that half of the array.
Here is a step-by-step breakdown of the binary search algorithm:
left
and right
, to the start and end of the array, respectively.left
is less than right
:
mid
.mid
is greater than the element at mid + 1
, then a peak must be in the left half, so set right
to mid
.left
to mid + 1
.left
equals right
, the peak element is found, and its index is returned./**
* @param {number[]} nums
* @return {number}
*/
function findPeakElement(nums) {
// Initialize left and right pointers
let left = 0;
let right = nums.length - 1;
// Binary search loop
while (left < right) {
// Calculate mid index
let mid = Math.floor((left + right) / 2);
// Check if mid element is greater than the next element
if (nums[mid] > nums[mid + 1]) {
// Peak is in the left half
right = mid;
} else {
// Peak is in the right half
left = mid + 1;
}
}
// Return the index of the peak element
return left;
}
The time complexity of the binary search approach is O(log n) because we are halving the search space in each iteration. The space complexity is O(1) as we are using a constant amount of extra space.
Some potential edge cases include:
These cases are handled effectively by the binary search algorithm.
To test the solution comprehensively, consider the following test cases:
[1]
[1, 2, 1, 3, 5, 6, 4]
[1, 2, 3, 4, 5]
[5, 4, 3, 2, 1]
Using a testing framework like Jest can help automate and validate these test cases.
When approaching such problems, consider the following tips:
In this blog post, we discussed how to find a peak element in an array using a binary search approach. We covered the problem definition, approach, algorithm, code implementation, complexity analysis, edge cases, and testing. Understanding and solving such problems is crucial for improving algorithmic thinking and coding skills.
For further reading and practice, consider the following resources:
Our interactive tutorials and AI-assisted learning will help you master problem-solving skills and teach you the algorithms to know for coding interviews.
Start Coding for FREE