原题
二分与排序中等2 种解法

#162寻找峰值

返回任意一个严格大于左右相邻元素的峰值下标,数组边界外视为负无穷。

#数组#二分查找

原题

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

给你一个整数数组 nums,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。

你可以假设 nums[-1] = nums[n] = -∞

你必须实现时间复杂度为 O(log 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。

提示:

  • 1 <= nums.length <= 1000
  • -231 <= nums[i] <= 231 - 1
  • 对于所有有效的 i 都有 nums[i] != nums[i + 1]

查看原题

解题主线

  1. 比较 nums[mid] 与 nums[mid + 1]:上坡时右侧必有峰值,下坡时 mid 及其左侧必有峰值。

解法 1:二分沿坡上行

保留必含峰值的一半区间,直到左右边界收敛。

  • 时间复杂度: O(log n)

  • 空间复杂度: O(1)

JAVA
final class Solution {
    public int findPeakElement(int[] nums) {
        int left = 0, right = nums.length - 1;
        // 循环不变量:闭区间 [left, right] 内至少存在一个峰值
        while (left < right) {
            int middle = left + (right - left) / 2;
            // 下坡时峰值可在 middle,故保留左半区并令 right = middle
            if (nums[middle] > nums[middle + 1]) right = middle;
            // 上坡时 middle 不可能是峰值,安全排除到 middle + 1
            else left = middle + 1;
        }
        return left;
    }
}

解法 2:寻找全局最大值

全局最大值在相邻不等的数组中一定是合法峰值。

  • 时间复杂度: O(n)

  • 空间复杂度: O(1)

JAVA
final class Solution {
    public int findPeakElement(int[] nums) {
        // 以首元素为当前最大值,单元素数组也自然返回 0
        int maximum = 0;
        for (int i = 1; i < nums.length; i++) {
            // 始终保存已扫描前缀的最大值下标
            if (nums[i] > nums[maximum]) maximum = i;
        }
        // 全局最大值不小于任一邻居,结合相邻不等即为严格峰值
        return maximum;
    }
}

边界与易错点

  • 二分循环使用 left < right,才能安全访问 mid + 1。
  • 题目保证相邻元素不相等;这是严格峰值存在性的关键。

整理来源

由旧仓库源码复核、去重并整理;展示代码已按 Java 21 语义修正明显问题。

  • easy/Q162_findPeakElement.java