LeetCode寻找峰值 二分查找
峰值元素是指其值严格大于左右相邻值的元素。
给你一个整数数组 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
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了