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,当左指针小于右指针循环继续

  • 中间位置midmid = left+(right-left)//2 or mid = (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最后返回left or right

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
posted on 2021-09-15 11:10  墩墩儿er  阅读(81)  评论(0)    收藏  举报