牛客100刷题寻找峰值

描述(注:寻找峰值_牛客题霸_牛客网)

给定一个长度为n的数组nums,请你找到峰值并返回其索引。数组可能包含多个峰值,在这种情况下,返回任何一个所在位置即可。

1.峰值元素是指其值严格大于左右相邻值的元素。严格大于即不能有等于

2.假设 nums[-1] = nums[n] = −∞

3.对于所有有效的 i 都有 nums[i] != nums[i + 1]

4.你可以使用O(logN)的时间复杂度实现此问题吗?

数据范围:

1≤nums.length≤2×10^5 

−2^31<=nums[i]<=2^31−1

如输入[2,4,1,2,7,8,4]时,会形成两个山峰,一个是索引为1,峰值为4的山峰,另一个是索引为5,峰值为8的山峰,如下图所示:

面对这个问题时,我认为主要是看清楚题目,并仔细分析要求。

也就是没有相等的相邻数据,当仅有一个值时,那个该值就是峰值

当n=>2时,峰值可能在最左边,最右边和中间,这三个地方。

下面写出代码:

class Solution:
    def findPeakElement(self , nums: List[int]) -> int:
        # write code here
        n=len(nums)
        if(n==1 or (nums[0]>nums[1])):
            return 0
        if(nums[n-1]>nums[n-2]):
            return n-1
        min,max=1,len(nums)-1
        while(min<max):
            mid=int((min+max)/2)
            if(nums[mid]>nums[mid-1] and (nums[mid]>nums[mid+1])):
                return mid
            if(nums[mid]<nums[mid-1]):
                max=mid
            if(nums[mid]<nums[mid+1]):
                min=mid
        return -1
import java.util.*;
public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * @param nums int整型一维数组 
     * @return int整型
     */
    public int findPeakElement (int[] nums) {
        // write code here
        int n=nums.length;
        if(n==1 || nums[0]>nums[1]){
            return 0;
        }
        if(nums[n-1]>nums[n-2]){
            return n-1;
        }
        int min=1;
        int max=n-1;
        while(min<max){
            int mid=(min+max)/2;
            if(nums[mid]>nums[mid-1]&&nums[mid]>nums[mid+1]){
                return mid;
            }
            if(nums[mid]<nums[mid-1]){
                max=mid;
            }
            if(nums[mid]<nums[mid+1]){
                min=mid;
            }
        }
        return -1;
    }
}

代码中前面两个if函数表示,我什么都不看,先看两段,能不能成为峰值,因为这两个端点只需要比较一次就可以出结果了。

把特别的要素排除:

n==1,表示仅有一个值。

第一个最左边端点:也就是索引为0,和索引为1比较。

第二个最右边端点:也就是索引为n-1,和索引为n-2比较。

如果以上都不是,那么只能在中间。

这里应用了二分类的方法,但是不同的地方在于判别语句中,不是target目标值和数相等,而是取mid的两边的数比较都小于mid,那就是我想要的结果mid。

这里依旧难点在于mid,min,max的取值。它们如何取,理念可以看二分类方法。

注:这里特别强调max和min的取值截断一半时,都是mid,不需要加1和减1,以免漏掉了。

个人总结:

对于该题,一定要读懂题目,难度可以小一半。

这里题目说明数组中相邻两个数不相等。那么二分法就很好寻找其中的值,而且时间复杂度也满足。

结果只需要输出一个峰值,不是所有峰值。那么可以一个个判别两段,这样最快的结果。最后再想中间的取值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值