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.
Input: nums =[1,2,3,1]Output: 2Explanation: 3is a peak element and your function should return the index number 2.
Example 2:
1
2
3
Input: nums =[1,2,1,3,5,6,4]Output: 5Explanation: Your function can return either index number 1 where the peak element is2, or index number 5 where the peak element is6.
A simple approach is to do a linear scan to a array and using few variables we can find a peak element. But the Time Complexity will be O(n) but real question is, Can we do better?
publicclassSolution {
// Function to find a peak element using recursionpublicintfindPeakElement(int[] nums) {
return findPeakElementRec(nums, 0, nums.length- 1);
}
// Helper function that uses recursion to find the peak elementprivateintfindPeakElementRec(int[] nums, int low, int high) {
int mid = low + (high - low) / 2;
// Check if mid is a peak elementif ((mid == 0 || nums[mid - 1]<= nums[mid])
&& (mid == nums.length- 1 || nums[mid + 1]<= nums[mid])) {
return mid;
}
// If the left neighbour is greater, then the peak lies in the left halfif (mid > 0 && nums[mid - 1]> nums[mid]) {
return findPeakElementRec(nums, low, mid - 1);
}
// If the right neighbour is greater, then the peak lies in the right// halfreturn findPeakElementRec(nums, mid + 1, high);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
deffind_peak_element(arr):
return find_peak_recursively(arr, 0, len(arr) -1, len(arr))
deffind_peak_recursively(arr, low, high, n):
mid = low + (high - low) //2# Check if the mid element is greater than or equal to its neighborsif (mid ==0or arr[mid] >= arr[mid -1]) and (
mid == n -1or arr[mid] >= arr[mid +1]
):
return arr[mid]
# If the element on the left side is greater, then there is a peak element on the left sideelif mid >0and arr[mid -1] > arr[mid]:
return find_peak_recursively(arr, low, mid -1, n)
# If the element on the right side is greater, then there is a peak element on the right sideelse:
return find_peak_recursively(arr, mid +1, high, n)