
Problem Statement
Given an integer array arr, it represents a mountain sequence where the numbers in the sequence increase to a maximum peak value and then begin to decrease. The task is to locate and return the index of this peak element. Unlike a traditional search which can operate in O(n) time, the solution for this problem must be optimized to run in O(log(n)) time complexity, akin to a binary search. This stringent time complexity requirement suggests that a direct linear search is insufficient, and a more sophisticated approach, leveraging the properties of the mountain sequence, is necessary.
Examples
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 <= 1050 <= arr[i] <= 106arris guaranteed to be a mountain array.
Approach and Intuition
To achieve the O(log(n)) time complexity, the problem closely mirrors the concept used in finding an element in a sorted array with a binary search. However, the twist here is that the array isn't fully sorted; it first rises to a peak and then declines. This unique structure enables the use of a modified binary search:
Initialize pointers: Start with two pointers,
leftat the beginning andrightat the end of the array.Binary search application: While
leftis less thanright:- Calculate
midas the average ofleftandright. - Check the elements adjacent to
arr[mid]. There are three cases:- If
arr[mid-1] < arr[mid] > arr[mid+1], you've found your peak; returnmid. - If
arr[mid-1] < arr[mid] < arr[mid+1], this implies that the peak is still to the right because the sequence is still ascending. Adjust theleftpointer tomid + 1. - If
arr[mid-1] > arr[mid] > arr[mid+1], this means the peak is to the left, so adjust therightpointer tomid - 1.
- If
- Calculate
Conclusion: The loop eventually narrows down to the peak, where
leftequalsright, the index of the peak element.
The rationale behind this approach capitalizes on the guaranteed presense of a single peak and no plateaus (i.e., no two equal maximum elements), as implies by the constraints and the definition of a mountain array. This ensures that the binary search modification effectively converges on the peak element.
Solutions
- C++
- Java
- Python
class Solution {
public:
int findMountainPeak(vector<int>& array) {
int left = 0, right = array.size() - 1, middle;
while (left < right) {
middle = (left + right) / 2;
if (array[middle] < array[middle + 1])
left = middle + 1;
else
right = middle;
}
return left;
}
};
The solution focuses on finding the peak index in a mountain array using C++. A mountain array is defined as an array where elements first increase to a peak where no two adjacent elements are equal, and then after the peak, the elements strictly decrease.
The approach utilized in the code is a binary search:
- Initialize
leftto 0 andrightto the last index of the array. - Implement a loop to continue while
leftis less thanright. - Calculate
middleas the average ofleftandright. - If the element at the
middleindex is less than the element atmiddle + 1, adjustleftto bemiddle + 1. - If the above condition doesn't hold, set
righttomiddle. - The loop exits when
leftequalsright, indicating the peak index is found.
The provided function, findMountainPeak, returns the peak index left after narrowing down its possible location through iterative comparisons. This method ensures a time complexity of O(log n), leveraging the efficiency of binary search.
class Solution {
public int findMountainTopIndex(int[] mountainArray) {
int low = 0, high = mountainArray.length - 1, middle;
while (low < high) {
middle = (low + high) / 2;
if (mountainArray[middle] < mountainArray[middle + 1])
low = middle + 1;
else
high = middle;
}
return low;
}
}
This solution helps find the peak index in a mountain array using Java. The method findMountainTopIndex accepts an array of integers representing the mountain array. A binary search technique is used to locate the peak efficiently:
- Initialize
lowto the first element index andhighto the last element index of the array. - Use a loop to continue searching as long as
lowis less thanhigh. - Calculate
middleas the average oflowandhighto get the middle index. - If the element at
middleis less than its next element, adjustlowtomiddle + 1. - If not, adjust
hightomiddle. - The loop exits when
lowequalshigh, which will be the index of the peak element (the highest element in the mountain array).
The binary search ensures the approach is efficient, running in O(log n) time complexity, making it suitable for large arrays.
class Solution:
def findPeakIndex(self, mountain: List[int]) -> int:
low = 0
high = len(mountain) - 1
while low < high:
middle = (low + high) // 2
if mountain[middle] < mountain[middle + 1]:
low = middle + 1
else:
high = middle
return low
This solution summary addresses the problem of finding the peak index in a 'mountain' array, an array where elements increase up to a peak point then decrease. The implementation uses a binary search algorithm to efficiently find the peak in O(log n) time complexity due to its divide-and-conquer approach.
- Start by initializing two pointers:
lowset to 0 andhighset to the last index of the array. - Enter a while loop where you continue until
lowis less thanhigh. - Calculate the middle index by averaging
lowandhigh. - Compare the element at the
middleindex with the element right after it (middle + 1). If themiddleelement is less thanmiddle + 1, adjustlowto search the upper half of the array, otherwise adjusthighto continue with the lower half. - Exit the loop when
lowequalshigh, which is when you have found the peak index.
Final result returned is the value of low, which corresponds to the peak index in the mountain array. This solution guarantees finding the peak under the mountain array's constraints, delivering both effectiveness and efficiency.