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


     

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

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

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

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

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

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

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

    唯一的可能就是这段区间[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;
        }
    }

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

  • 相关阅读:
    Centos6.5下搭建nagios详解
    Centos6.5下升级Python版本
    Python生成随机密码
    配置apache使用https访问
    Irrlicht 论坛好贴 精选(不断补充中...)
    [原创]一个在Irrlicht中会常用的字符串转换函数
    [转]Scrolling Credits Code
    [原创]Irrlicht中的Texture透明色(colorkey)
    [原创]IrrLicht的GUI使用
    [转](C++) How to animate and move an entity
  • 原文地址:https://www.cnblogs.com/take-it-easy/p/13399847.html
Copyright © 2020-2023  润新知