LeetCode 数组:162. 寻找峰值(二分法)

 

 做这道题目的问题在于,学会了套路,却忘记了分析问题的独特性。

当然,采取双指针我们可以在ON的时间复杂度解决。

OlogN这个条件其实暗示了很多信息,一般见到无非是二分查找或者二叉树搜索。我想了想,觉得二分查找一般好像是找某个范围内的整数 ,想了想好像对这个题目没什么影响。然后就想怎么把这些数据放到搜索树然后能解决问题了。

重要的一点在于,没有关注两侧是负无穷这个条件。如果没有这个条件,问题都是局部的,nums[1]是不是峰值和nums[5]是不是峰值之间好像没有什么关系,只需要关注前面和后面两个值才能判断。

具体分析这个题目,其实归纳出的规律是:“只要数组中存在一个元素比相邻元素大,那么沿着它一定可以找到一个峰值”。

首先,整个区间必然会出现峰值,无论是单调增减,单峰还是驼峰。

其次,设想一下,nums[n]到nums[length-1]这个区间不出现峰值有哪些可能情况(二分法的思维):

扫描二维码关注公众号,回复: 11468186 查看本文章

唯一的可能就是这段区间[nums[n-1],nums[length-1]单调递减。

所以来捋一捋二分法的几个关键条件:

  • 区间划分:采取传统的左闭右开区间,左右分别为l,r,初始设置为0,length
  • 终止条件:当区间只有一个值时,即while(r>l+1)时进行二分
  • mid=l+r /2,区间分别是[l,mid),[mid,r)。当nums[mid]>nums[mid-1]时右区间有峰值,反之左区间有峰值

所以代码就出来了:(迭代二分法,当然还有递归的二分法)

public class Solution {
    public int findPeakElement(int[] nums) {
        int l = 0, r = nums.length;
        while (l +1 < r) {
            int mid = (l + r) / 2;
            if (nums[mid] > nums[mid - 1])
                l = mid;
            else
                r = mid;
        }
        return l;
    }
}

这道题给我的启发是:二分法的中心在于能通过比较区分范围是在左区间还是右区间,什么整数什么的都是外壳

猜你喜欢

转载自www.cnblogs.com/take-it-easy/p/13399847.html