说一下思路过程
首先要求 logn 的复杂度,那肯定用二分
考虑到首末两个点,如果这两个点不是峰值,那峰值就一定在在两个点之间(例如 nums[1] > nums[0],那么峰值至少是nums[1])
考虑二分,从中间开始,如果中间值小于左边值,那么峰值一定存在于这两点之间。右边亦然。
如果中间值大于两边值,那么判断中间值是否为峰值,如果不是,就朝不是那一边二分
提交后能以 0ms 通过,但是显然代码太复杂了
重新思考二分的条件
发现只需要考虑中间点是否是峰值就可以了
如果是就返回答案
如果不是,选择导致它不是的那一边继续二分(可以看成一个上坡的过程,始终找上坡的那一边),如果最后峰值就是首末两点,那么最终还是会返回首末两点,不需要提前考虑
自己的(修改前 0ms)
class Solution {
public int findPeakElement(int[] nums) {
if(nums.length == 1 || nums[1] < nums[0] )
return 0;
if(nums[nums.length - 1] > nums[nums.length - 2])
return nums.length - 1;
int l = 0,r = nums.length - 1;
while(l < r){
int mid = (l + r) / 2;
if(nums[mid] <= nums[l])
r = mid;
else
if(nums[mid] <= nums[r])
l = mid + 1;
else
if(nums[mid] < nums[mid - 1])
r = mid;
else
if(nums[mid] < nums[mid + 1])
l = mid + 1;
else
return mid;
}
return l;
}
}
自己的(修改后0ms)
class Solution {
public int findPeakElement(int[] nums) {
if(nums.length == 1)
return 0;
int l = 0,r = nums.length - 1;
while(l < r){
int mid = (l + r) / 2;
if(nums[mid] < nums[mid + 1])
l = mid + 1;
else
r = mid;
}
return l;
}
}