162. 寻找峰值

在这里插入图片描述

因为给出了复杂度要求,可以想到使用二分法。

但是关键就在于二分的那个点.
nums[mid]可能大于左边或者大于右边的数,也可能小于左边或者右边的数,我们来讨论一下具体的情况

  1. nums[mid]小于左边或者右边的某一个数,或者小于两边的数。
  2. nums[mid]大于左右两边的数。

对于情况二,就是要找的峰值。
而对于情况1,我们的二分查找接下来倒底是往左边还是右边查找呢?
我们假定右边的数大于当前的nums[mid]

那么我们一定在右边可以找到峰值!(左边也可能找到)原因如下:
对于右边剩下的数,不管是递增还是递减,还是无序(也就是随意排列),那么总会有一个最大的数。
那么这个数肯定大于左右两边的数(即使这个数是mid+1这个位置的。注意nums[n]=负无穷)。

而如果此时我们选择查找左边,如果最大值不是mid-1这个的话,那也能找到驼峰,但是如果不幸是的话,那就gg了。

可以画折线图来演示
class Solution {
 public int findPeakElement(int[] nums) {

        int n = nums.length;
        int idx = 0;
        int l = 0, r = n - 1;
        while (l < r) {
            int mid = l + r >> 1;
//一直往大的那块区域查找,按照之前的所说的,一定存在峰值
            if ((mid + 1 < n && nums[mid] < nums[mid + 1])) {
                l = mid+1;
            } 
            //else有两种情况:左边可能也是大的那块区域,或者当前mid就是峰值,
            //那么r=mid,左边也一定有峰值
            
            else  {
                r = mid;
            }

        }
        return l;
    }
}

代码这里不用担心越界的情况,因为其实我们利用else避免了越界,同时其实mid+1<n也不需要判断了,因为我们l+r>>1会使得mid一定小于n-1(l=r=n-1时才可能使mid为n-1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值