[LeetCode] 162. 寻找峰值

题目链接 : https://leetcode-cn.com/problems/find-peak-element/

题目描述:

值元素是指其值大于左右相邻值的元素。

给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引。

数组可能包含多个峰值,在这种情况下,返回任何一个峰值所在位置即可。

你可以假设 nums[-1] = nums[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(logN) $时间复杂度的。

思路:

刚看到这题,这不就是一遍遍历吗,刷刷刷,写出来下面的代码

class Solution(object):
    def findPeakElement(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        nums = [float("-inf")] + nums + [float("-inf")]
        n = len(nums)
        for i in range(1, n - 1):
            if nums[i - 1] < nums[i] and nums[i] > nums[i + 1]:
                return i - 1

但是, 题目要求是 \(O(log N)\),明显这是\(O(n)\)的,还有一种\(O(n)\)一次遍历算法

class Solution(object):
    def findPeakElement(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        for i in range(1, len(nums)):
            if nums[i - 1] > nums[i]:
                return i - 1
        return len(nums) - 1

很神奇吧,言归正传!这题要求局部最大值,又要用二分法,参考链接[1]

我不是太明白, 但是大家可以用极端角度考虑一下,模拟一下过程,找找感觉!

如果这个数组按顺序排列的?如果这个数组为 [1, 2]呢?有谁可以把它说明白吗?

class Solution(object):
    def findPeakElement(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        left = 0
        right = len(nums) - 1
        while left < right:
            mid = left + (right - left) // 2
            if nums[mid] < nums[mid + 1]:
                left = mid + 1 
            else:
                right = mid
        return left

  1. https://leetcode.com/problems/find-peak-element/discuss/50232/Find-the-maximum-by-binary-search-(recursion-and-iteration) ↩︎

posted on 2019-08-02 19:19  威行天下  阅读(274)  评论(0编辑  收藏  举报

导航