描述
给定一个长度为n的数组nums,请你找到峰值并返回其索引。数组可能包含多个峰值,在这种情况下,返回任何一个所在位置即可。
- 峰值元素是指其值严格大于左右相邻值的元素。严格大于即不能有等于
- 假设 nums[-1] = nums[n] = Integer.MIN_VALUE
- 对于所有有效的 i 都有 nums[i] != nums[i + 1]
数据范围:
- 1<n<=2x10^5
- -2^31<=nums[i]<=2^31-1
思路1:寻找最大值
省略
思路2:遍历左右比较
思路1和思路2,最差的情况坡峰在最后一个值,时间复杂度为O(n)
public class Solution {
public int findPeakElement (int[] nums) {
int left = Integer.MIN_VALUE;
for(int i = 0; i < nums.length - 1; i++) {
if(nums[i] > left && nums[i] > nums[i+1]) {
return i;
}
left = nums[i];
}
return nums.length - 1;
}
}
思路3:二分法
下坡不一定有坡峰,上坡一定有坡峰,不断压缩区间。时间复杂度为O(logn)
public class Solution {
public int findPeakElement (int[] nums) {
int i = 0;
int j = nums.length - 1;
while(i < j) {
int mid = i + (j - i >> 1);
if(nums[mid] < nums[mid + 1]) {
//mid小于mid+1,说明mid不可能是坡峰,可以跳过
i = mid + 1;
} else {
//mid>=mid+1,mid有可能是坡峰,不能跳过
j = mid;
}
}
return i;
}
}