LeetCode_162. 寻找峰值(对无序的数组进行二分查找操作)局部最大

在这里插入图片描述

思路(参考宫水三叶🙇‍)

确保有解的情况之下,我们可以根据 mid 将数组分为两段,根据当前的分割点 mid 与左右元素的大小关系来指导 left 或者 right 的移动,然后判断有没有峰值。

首先得到mid,然后比较 nums[mid] 和 nums[mid+1] ,如果nums[mid] > nums[mid+1],说明mid的值大于其右边的值,所以nums[mid]可能为峰值,而 nums[mid+1] 一定不是峰值,于是就让right=mid,从左半部分继续找峰值。

分析

保证上述思路及做法正确有个前提:

  1. 对于任意数组,一定有峰值(一定有解)
    上面特意加粗了 确保有解 ,我们有「数据长度至少为 1」、「越过数组两边看做负无穷」和「相邻元素不相等」的起始条件。

    1. 数组长度为1,且两边边界为负无穷,所以 nums[0] 就是峰值。
    2. 如果长度大于一:
      - 如果 nums[0] > nums[1],那么最左边元素 nums[0] 就是峰值(结合左边界为负无穷)
      - 如果 nums[0] < nums[1],由于已经存在明确的 nums[0] 和 nums[1] 大小关系,我们将 nums[0] 看做边界, nums[1] 看做新的最左侧元素,继续往右进行分析:
      1. 如果在到达数组最右侧前,出现 nums[i]>nums[i+1],说明存在峰值位置 i(当我们考虑到 nums[i],必然满足 nums[i] 大于前一元素的前提条件,当然前一元素可能是原始左边界)
      2. 到达数组最右侧,还没出现 nums[i]>nums[i+1],说明数组严格递增。此时结合右边界可以看做负无穷,可判定 nums[n−1] 为峰值。
  2. 二分不会错过峰值
    如果当前位置大于其左边界或者右边界,那么在当前位置的右边或左边必然存在峰值
    我们始终选择大于边界一端进行二分,可以确保选择的区间一定存在峰值,并随着二分过程不断逼近峰值位置。

实现代码(java)

class Solution {
    public int findPeakElement(int[] nums) {
        int l = 0;
        int r = nums.length - 1;
        while (l < r) {
            int mid = l + (r - l) / 2;
            if (nums[mid] > nums[mid+1]) r = mid;
            else l = mid + 1;
        }
        return r;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值