1. 寻找峰值
(1)一次遍历(O(n))
首先要考虑:
- nums[-1] 和 nums[n] 等于多少
- 存不存在nums[i] != nums[i+1],存在二分就可能找不到
由题意可知因为 nums[-1] = nums[n] = -oo
所以,只要找到 nums[i] > nums[i + 1],即找到峰值
class Solution {
public int findPeakElement(int[] nums) {
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i] > nums[i + 1])
return i;
}
return nums.length - 1;
}
}
(2)二分(O(logN))
有如下规律:
- 如果nums[i] > nums[i+1],则在i之前一定存在峰值元素
- 如果nums[i] < nums[i+1],则在i+1之后一定存在峰值元素
class Solution {
public int findPeakElement(int[] nums) {
int left = 0, right = nums.length - 1;
//搜索区间可以定义为[left,right] + 1,所以这里定义right = nums.length - 1;
//按照传统的二分,应该是一个左闭右闭的区间,但是nums[mid] > nums[mid + 1],实际上最后一个不可取
//又变成了左闭右开
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid] > nums[mid + 1]) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
}