> For the complete documentation index, see [llms.txt](https://imhuay.gitbook.io/studies/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://imhuay.gitbook.io/studies/algorithms/problems/2022/04/niu-ke-0107-zhong-deng-xun-zhao-feng-zhi.md).

# 寻找峰值

![last modify](https://img.shields.io/static/v1?label=last%20modify\&message=2022-10-14%2014%3A59%3A33\&color=yellowgreen\&style=flat-square) [![](https://img.shields.io/static/v1?label=\&message=%E4%B8%AD%E7%AD%89\&color=yellow\&style=flat-square)](https://imhuay.gitbook.io/studies/algorithms/problems/2022/04/pages/R5NyOzkn3qAZy7wCx1pS#中等) [![](https://img.shields.io/static/v1?label=\&message=%E7%89%9B%E5%AE%A2\&color=green\&style=flat-square)](https://imhuay.gitbook.io/studies/algorithms/problems/2022/04/pages/R5NyOzkn3qAZy7wCx1pS#牛客) [![](https://img.shields.io/static/v1?label=\&message=%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE\&color=blue\&style=flat-square)](https://imhuay.gitbook.io/studies/algorithms/problems/2022/04/pages/R5NyOzkn3qAZy7wCx1pS#二分查找) [![](https://img.shields.io/static/v1?label=\&message=%E7%BB%8F%E5%85%B8\&color=blue\&style=flat-square)](https://imhuay.gitbook.io/studies/algorithms/problems/2022/04/pages/R5NyOzkn3qAZy7wCx1pS#经典)

> [寻找峰值\_牛客题霸\_牛客网](https://www.nowcoder.com/practice/fcf87540c4f347bcb4cf720b5b350c76)

**问题简述**

```
给定一个长度为n的数组nums，请你找到峰值并返回其索引。数组可能包含多个峰值，在这种情况下，返回任何一个所在位置即可。
1.峰值元素是指其值严格大于左右相邻值的元素。严格大于即不能有等于
2.假设 nums[-1] = nums[n] = -inf
3.对于所有有效的 i 都有 nums[i] != nums[i + 1]

进阶：时间复杂度 O(logN)
```

**思路1：遍历**

* 注意问题中假设左右边界为**负无穷**，因此当数组中只有一个或两个元素时也是存在答案的；

<details>

<summary><strong>Python</strong></summary>

```python
class Solution:
    def findPeakElement(self , nums: List[int]) -> int:
        
        nums = nums + [float('-inf')]
        pre = float('-inf')
        for i in range(len(nums)):
            if nums[i] > pre:
                mx_i = i
            if nums[i] < pre:
                return mx_i
            pre = nums[i]
```

</details>

**思路2：找最大值**

* 根据问题定义，最大值必定是答案之一

<details>

<summary><strong>Python</strong></summary>

```python
class Solution:
    def findPeakElement(self , nums: List[int]) -> int:
        
        return nums.index(max(nums))
```

</details>

**思路3：二分（最佳）**

* 可以通过比较 `nums[m]` 和 `nums[m + 1]` 可以确定所在位置是“上坡”还是“下坡”；
* 注意：二分有效的前提是 `对于所有有效的 i 都有 nums[i] != nums[i + 1]`；

<details>

<summary><strong>Python</strong></summary>

```python
class Solution:
    def findPeakElement(self , nums: List[int]) -> int:
        
        l, r = 0, len(nums) - 1
        while l < r:
            m = (l + r) // 2
            if nums[m] < nums[m + 1]:  # 上坡；因为 l < r，所以 m+1 不会越界
                l = m + 1
            else:  # 下坡
                r = m 
                if m == 0 or nums[m - 1] < nums[m]:  # 这段去掉也能 AC
                    return m
        
        return l
```

</details>
