162. 寻找峰值

https://leetcode-cn.com/problems/find-peak-element/

解法一:二分(递归分治)

class Solution:
    def findPeakElement(self, nums: List[int]) -> int:
        n = len(nums)
        #边界
        if n == 1:
            return 0
        elif n == 2:  #长度为2时取较大的
            return 0 if nums[0] > nums[1] else 1
        #长度>=3
        else:
            mid = n // 2  #取中点
            #若中点比两侧大,直接去中点
            if nums[mid-1] < nums[mid] > nums[mid+1]:
                return mid
            #若左侧大,说明左侧可能存在山峰,递归处理左侧数组
            elif nums[mid-1] > nums[mid]:
                return self.findPeakElement(nums[:mid])
            #否则递归处理右侧
            else:
                return mid+1 + self.findPeakElement(nums[mid+1:])

解法二:还是二分

其实也不用递归,不仅慢,占用内存还多,直接传统二分

class Solution:
    def findPeakElement(self, nums: List[int]) -> int:
        low, high = 0, len(nums)-1
        mid = 0
        while low < high:
            mid = (low + high) // 2
            #区间只有两个元素时,特殊处理(防止下面判断越界)
            #直接令mid等于较大元素的下标
            if high - low == 1:
                mid = high if nums[high] > nums[low] else low
                break
            #若mid是山峰
            if nums[mid-1] < nums[mid] > nums[mid+1]:
                break
            #左侧更大,对左侧二分
            elif nums[mid-1] > nums[mid]:
                high = mid-1
            #否则右侧
            else:
                low = mid+1
        #若区间缩减为一个元素,即为所求
        if low == high:
            return low
        #否则mid为所求
        return mid

解法三:暴力

首尾添加负无穷元素,然后一次遍历,结果和二分一样快,奇了怪

class Solution:
    def findPeakElement(self, nums: List[int]) -> int:
        nums.insert(0, -sys.maxsize)
        nums.append(-sys.maxsize)
        for i in range(len(nums)-1):
            if nums[i-1] < nums[i] > nums[i+1]:
                return i-1  #注意首尾加了辅助元素

最后更新于