题目
BM19 寻找峰值
描述
给定一个长度为n的数组nums,请你找到峰值并返回其索引。数组可能包含多个峰值,在这种情况下,返回任何一个所在位置即可。
分析
对一个左闭右闭的区间二分,通过改变l 或r 的值将原始查找区间缩小一半,根据nums[mid]与nums[mid-1] 的值的大小比较,取有上升趋势的那一半区间(因为有上升趋势的这一半区间才会存在峰值),最后当l == r 的时候,跳出while, l 或r的值就是一个峰值下标。
ps: 要注意,不能将nums[mid]向左比较nums[mid-1],向左比较的话有可能访问到nums[-1],只能向右与nums[mid+1]比较,向右比较的话,mid的值向下取整最多取到 r-1,mid+1最多取到 lenth-1,就不会越界。
代码
class Solution:
def findPeakElement(self , nums: List[int]) -> int:
# 向左比较代码不通过
# l , r = 0, len(nums)-1
# while(l<r):
# mid = (l+r)//2
# if nums[mid]< nums[mid-1]:
# r = mid-1
# else:
# l = mid
# return l
# 在一个区间内找到一个局部最大值,当l=r时跳出循环找到最大值的下标,所以while中不写等号
# 能与 mid+1 比较,但是不能与mid-1比较的原因:向左比较的话有可能访问到nums[-1],但是向右比较的话,mid的值向下取整最多取到 r-1,mid+1最多取到 lenth-1,就不会越界
# 向右比较
l , r = 0, len(nums)-1
while(l<r):
mid = (l+r)//2
if nums[mid]< nums[mid+1]:
l = mid+1
else:
r = mid
return l
另外提供一份python偷懒代码:
事实证明,练习的时候不能偷懒
class Solution:
def findPeakElement(self , nums: List[int]) -> int:
return nums.index(max(nums))