162.寻找峰值
峰值元素是指其值严格大于左右相邻值的元素。给你一个整数数组
nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。你可以假设
nums[-1] = nums[n] = -∞。你必须实现时间复杂度为
O(log n)的算法来解决此问题。
题目链接:162. 寻找峰值 - 力扣(LeetCode) (leetcode-cn.com)
暴力解法(循环遍历整个数组,直到找到峰值并返回)
class Solution:
def findPeakElement(self, nums: List[int]) -> int:
nums = [-float('inf')]+nums+[-float('inf')]
n = len(nums)
for i in range(1,n-1):
if nums[i]>nums[i-1] and nums[i]>nums[i+1]:
return i-1
二分解法
-
由于题目已经给出假设
nums[-1] = nums[n] = -∞由此可以得出此数组构成的曲线必定存在一个以上的峰值。 -
随便画一条有峰值的曲线可以发现,沿着较大元素的方向一定可以找到一个峰值
-
可以使用二分查找算法,设置左指针
left和右指针right,当左指针小于右指针循环继续 -
中间位置
mid(mid = left+(right-left)//2ormid = (left+right)//2) -
将中间位置的数字与两边的数字进行比较:
- 若
nums[mid-1]<nums[mid] and nums[mid]>nums[mid+1]则返回mid - 否则 若
nums[mid+1]>nums[mid]则右侧必有峰值left = mid+1 - 否则
nums[mid-1]>nums[mid]左侧必有峰值right = mid-1
- 若
-
退出
while的条件left==right最后返回leftorright
class Solution:
def findPeakElement(self, nums: List[int]) -> int:
n = len(nums)
left = 0
right = n-1
while(left<right):
mid = (left+right)//2
if nums[mid]>nums[mid+1] and nums[mid]>nums[mid-1]:
return mid
else:
if nums[mid+1]>nums[mid]:
left = mid+1
else:
right = mid-1
return left
浙公网安备 33010602011771号