LeetCode寻找峰值 二分查找

162. 寻找峰值

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

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

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

你必须实现时间复杂度为 O(log n) 的算法来解决此问题。

示例 1

输入:nums = [1,2,3,1]

输出:2

解释:3 是峰值元素,你的函数应该返回其索引 2

示例 2

输入:nums = [1,2,1,3,5,6,4]

输出:1 5

解释:你的函数可以返回索引 1,其峰值元素为 2

     或者返回索引 5 其峰值元素为 6

思路:

    题目说了用复杂度为O(log n)的算法来解决此问题,本来还不知道思路,现在一下就有了:二分查找

    用二分查找,只需要改变我们判断“找到”的条件即可,这个条件从传统的单纯等于某个值变为满足峰值的定义:大于左右两边的值

    要注意的是,如果这个值在最左端,或者最右端,那么它有一边就已经满足峰值条件了,只需要再判断它是不是比另一端大就可以,如果比如[3,1]3就是峰值,[1,4,5]5就是峰值。

代码:

class Solution(object):

    def findPeakElement(self, nums):

        n = len(nums)#获得数组长度n

        left, right = 0, len(nums) – 1#left和right分别在左和右

        while left <= right:#二分查找开始

            mid = (left + right) // 2

           #找到峰值的条件

            if (mid==0 or nums[mid]>nums[mid-1]) and (mid==n-1 or nums[mid]>nums[mid+1]):
            #比左边大 and  比右边大
                return mid #符合条件,直接返回

           #其他情况

           #如果只满足比右边大,证明左边还有比mid值更大的

            if nums[mid] > nums[mid + 1]:

                right = mid – 1#向左收敛

            else:#如果右边还有比mid值更大的

                left = mid + 1#向右收敛

  代码中mid==0表示当前位置在最左端,等价于满足它大于左边的数即nums[mid]>nums[mid-1]mid==n-1同理。

  最后,顺带一提:在原来的提交记录中还发现了另一个很抽象但简洁的二分查找实现,但似乎也是可通过的。这种不太好理解的方法就随便贴一下吧,就不做注释和分析了,有兴趣的可以拿去提交和琢磨一下为啥这个也可行哈哈哈。

class Solution(object):

    def findPeakElement(self, nums):

        left, right = 0, len(nums) - 1

        while left < right:

            mid = (left + right) // 2

            if nums[mid] > nums[mid + 1]:

                right = mid

            else:

                left = mid + 1

        return left

posted @   JunanP  阅读(9)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示