Leetcode: Find Peak Element, leetcodepeak
A peak element is an element that is greater than its neighbors.Given an input array where num[i] ≠ num[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 num[-1] = num[n] = -∞.For example, in array [1, 2, 3, 1], 3 is a peak element and your function should return the index number 2.click to show spoilers.Note:Your solution should be in logarithmic complexity.
This question is still a little troublesome and requires the time complexity of O (logN). I want to use binary search. If the intermediate element is greater than its adjacent subsequent element, the left side of the intermediate element (including the intermediate element) must contain a local maximum value. If the intermediate element is smaller than its adjacent subsequent element, the right side of the intermediate element must contain a local maximum value. Until the last left side meets the right side
Here are some notes:
1. Here, we only choose to discuss the size of the intermediate element mid and Its Adjacent Elements mid + 1, instead of the previous element mid-1, which is mainly convenient. Mid = (left + right)/2. This division has a floor effect in it, that is, lift (left + right)/2 trim ⌋. In this case, when left and right are different, the index is mid and mid + 1, but mid-1 may be less than 0. In this way, when mid = 0, the elements of mid-1 have to be discussed in particular, which is troublesome. For example, left = 0, right = 1, mid = 0, mid-1 =-1, mid + 1 = 1, do not want to discuss the situation of mid-1
2. if the intermediate element is greater than its adjacent subsequent element, it indicates that the left side of the intermediate element (including the intermediate element) must contain a local maximum value. At this time, the intermediate element may be a local maximum point, therefore, move r = mid instead of r = mid-1. If the intermediate element is smaller than its adjacent subsequent element, the right side of the intermediate element must contain a local maximum value. At this time, the intermediate element is certainly not the local largest point, so move l = mid + 1
3. The reason why we need to use the left and right sides to encounter each other is that we do not want to involve the mid-1 issue. Otherwise, the condition is num [mid]> num [mid + 1] & num [mid]> num [mid-1] and the split condition mid = 0
4. If mid is a valley, such as [1, 2, 1, 6, 7], I don't know where to jump? In this case, you can jump to the left to the right. You can specify either a direction or 2 to the left or 7 to the right (it is also a peak value as defined ). Because we only need to find one, we still use O (logN)
1 public class Solution { 2 public int findPeakElement(int[] num) { 3 int l = 0; 4 int r = num.length - 1; 5 while (l <= r) { 6 if (l == r) return l; 7 int mid = (l + r)/2; 8 if (num[mid] < num[mid+1]) { 9 l = mid + 1;10 }11 else {12 r = mid;13 }14 }15 return -1;16 }17 }
On the Internet, another method is to honestly compare the relationship between the mid and the front and back elements:
1 public int findPeakElement(int[] num) { 2 int n = num.length; 3 if (n <= 1) return 0; 4 // handle the first and last element in num[] 5 if (num[0] > num[1]) return 0; 6 if (num[n - 1] > num[n - 2]) return n - 1; 7 int left = 1, right = n - 2; 8 while (left <= right) { 9 int mid = (left + right) >> 1;10 if (num[mid] > num[mid - 1] && num[mid] > num[mid + 1]) {11 return mid;12 } else if (num[mid] > num[mid + 1]) {13 right = mid - 1;14 } else {15 left = mid + 1;16 }17 }18 return -1;19 }