leetcode 162 寻找峰值

162 寻找峰值

峰值元素是指其值大于左右相邻值的元素。
给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引。
数组可能包含多个峰值,在这种情况下,返回任何一个峰值所在位置即可。
你可以假设 nums[-1] = nums[n] = -∞。

示例 1:

输入: nums = [1,2,3,1]
输出: 2
解释: 3 是峰值元素,

示例 2:

输入: nums = [1,2,1,3,5,6,4]
输出: 1 或 5 
解释: 你的函数可以返回索引 1,其峰值元素为 2;
     或者返回索引 5,

说明:

你的解法应该是 O(logN) 时间复杂度的。

这题注意是 中等难度的,做之前感觉有点不合理,以为应该是 easy,做之后,发现确实应该是 medium ,看博客基本都说二分,感觉都没说到重点?为什么能用二分?
首先注意复杂度要求,会想到二分,然后又想到数组是无序的,不适合用二分,但是除了二分也不可能满足该复杂度要求了。所以确定用二分。
然后,这题考的是数学。
两端是最低点,所以这题一定有解,而且题目要求任意解即可,因此可以用二分。
这题只要理解了这一点,就能做出来核心思想:取mid值,只要nums[mid-1] 大于nums[mid] ,则mid左边一定有峰值 反之,mid-1右边一定存在峰值,因为两端无穷小,明白不了的画张图理解一下
然后,看代码注释

var findPeakElement = function(nums) {
    if(nums.length==1){
        return 0;
    }
    var l=0;
    var r=nums.length-1;
    //这里需要注意一下 js的 / 号不是整除
    var mid=Math.floor((l+r)/2);
    while(l<=r){
      //最后的结果必然是 l,r相邻,此时取两者之间大的一定是峰值
        if(mid==l){
            return nums[l]>nums[r]?l:r;
        }
        else if(nums[mid-1]>nums[mid]){
            r=mid;
        }
        else{
            l=mid;
        }
        mid=Math.floor((l+r)/2);
    }
};


你可能感兴趣的:(寻找峰值,二分查找,leetcode162)