Leetcode 162-寻找峰值

峰值元素是指其值严格大于左右相邻值的元素。

给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。

你可以假设 nums[-1] = nums[n] = -∞ 。

你必须实现时间复杂度为 O(log n) 的算法来解决此问题。
在这里插入图片描述

题解

题解转载自灵茶山艾府

标签:二分查找

定理:如果i<n−1且nums[i]<nums[i+1],那么在下标[i+1,n−1]中一定存在至少一个峰值。

证明:反证法,假设下标[i+1,n−1]中没有峰值。
由于i+1不是峰值且nums[i]<nums[i+1],所以一定有nums[i+1]<nums[i+2]成立,否则i+1就是峰值了。注意题目保证相邻元素不同,不存在相邻元素相等的情况。
由于i+2不是峰值且nums[i+1]<nums[i+2],所以一定有nums[i+2]<nums[i+3]成立,否则i+2就是峰值了。
依此类推,得
nums[i]<nums[i+1]<nums[i+2]<⋯<nums[n−1]>nums[n]=−∞
这意味着nums[n−1]是峰值,矛盾,所以原命题成立。

同理可得,如果i<n−1且nums[i]>nums[i+1],那么在[0,i]中一定存在至少一个峰值。

所以,通过比较nums[i]和nums[i+1]的大小关系,从而不断地缩小峰值所在位置的范围,二分找到峰值。

/*
定理:如果i<n−1且nums[i]<nums[i+1],那么在下标[i+1,n−1]中一定存在至少一个峰值。
同理可得,如果i<n−1且nums[i]>nums[i+1],那么在[0,i]中一定存在至少一个峰值。

所以,通过比较nums[i]和nums[i+1]的大小关系,从而不断地缩小峰值所在位置的范围,二分找到峰值。
*/
class Solution {
    public int findPeakElement(int[] nums) {
        int left=0,right=nums.length-1;
        while(left<right){
            int mid=(left+right)/2;
            if(nums[mid]<nums[mid+1]) left=mid+1;
            else right=mid;
        }
        return left;
    }
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值