You are given an integer mountain array arr
of length n
where the values increase to a peak element and then decrease.
Return the index of the peak element.
Your task is to solve it in O(log(n))
time complexity.
Example 1:
Input: arr = [0,1,0]
Output: 1
Example 2:
Input: arr = [0,2,1,0]
Output: 1
Example 3:
Input: arr = [0,10,5,2]
Output: 1
Constraints:
3 <= arr.length <= 105
0 <= arr[i] <= 106
arr
is guaranteed to be a mountain array.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
Imagine you are climbing a mountain and need to find the very top. The brute force way is like checking the height at every single point to find the highest one. It’s like going through every possible spot until you find the peak.
Here's how the algorithm would work step-by-step:
def find_peak_index_brute_force(mountain_array):
array_length = len(mountain_array)
for current_index in range(array_length - 1):
# We check if the current element is greater
# than the next to identify the peak.
if mountain_array[current_index] > mountain_array[current_index + 1]:
return current_index
#The current element is smaller than the next
#We check if it's the last element, if so it is the peak
if current_index == array_length - 2:
return current_index + 1
The optimal strategy is to use a method similar to searching in a phone book. Instead of checking each entry one by one, we repeatedly cut the possible search area in half until we find what we are looking for. This is much faster than looking at every single entry.
Here's how the algorithm would work step-by-step:
def peakIndexInMountainArray(arr):
left_index = 0
right_index = len(arr) - 1
while left_index < right_index:
middle_index = (left_index + right_index) // 2
# Check if the peak is to the left of the middle index.
if arr[middle_index - 1] > arr[middle_index]:
right_index = middle_index
# Check if the peak is to the right of the middle index.
elif arr[middle_index + 1] > arr[middle_index]:
left_index = middle_index + 1
# Middle is peak if neither left nor right are bigger.
else:
return middle_index
# When left and right meet, it's the peak.
return left_index
Case | How to Handle |
---|---|
Null or empty input array | Throw an IllegalArgumentException or return -1 to indicate invalid input. |
Array with only one element | Throw an IllegalArgumentException or return -1 since it doesn't satisfy mountain array properties. |
Array with two elements | Throw an IllegalArgumentException or return -1 as it cannot form a mountain. |
Array with only increasing elements | Throw an IllegalArgumentException or return -1 because there is no peak. |
Array with only decreasing elements | Throw an IllegalArgumentException or return -1 because there is no peak. |
Integer overflow during calculation of mid index in binary search | Use mid = low + (high - low) / 2 to prevent potential overflow. |
Large array size exceeding available memory | The binary search approach has logarithmic space complexity, so memory should not be a concern for typical input sizes. |
Array with numbers at Integer.MAX_VALUE or Integer.MIN_VALUE | Handle carefully during comparison to prevent any integer overflow issues. |