LC 162. 寻找峰值

LC 162. 寻找峰值

题目链接

162. 寻找峰值

题目思路

  1. 判断数组第一个元素和最后一个元素的上升下降趋势,如果 nums[0] > nums[1] ,0 就是峰值。如果 nums[n - 1] > nums[n - 2] ,n - 1 就是峰值。

  2. 如果 nums[0]nums[n - 1] 均不是峰值。从 nums[0]nums[1] 是 ↗ 的。从 nums[n - 2]nums[n - 1] 是 ↘ 的。根据罗尔定理,在 nums[1, n - 2] 之间一定存在峰值。可以通过不断的二分查找,找到这个峰值。

  3. 通过比较数组中间元素 nums[m] 的值和 nums[m - 1]nums[m + 1] 值的大小来决定下次二分的范围。

    1. nums[m] < nums[m - 1]nums[0]nums[1] 是 ↗ 的,nums[m - 1]nums[m] 是 ↘ 的,因此,峰值在左半部分[1, m - 1]
    2. nums[m] < nums[m + 1]nums[m]nums[m + 1] 是 ↗ 的,nums[n - 2]nums[n - 1] 是 ↘ ,因此,峰值在左半部分 [m + 1, n - 2]
  4. 最后,一定能二分到 nums[m],满足 nums[m - 1] < nums[m]nums[m] > nums[m + 1] 均成立,m 就是峰值下标。返回即可

寻找峰值

题目代码

class Solution {
    public int findPeakElement(int[] nums) {
        int n = nums.length;
        
        if (n == 1) return 0;
        if (nums[0] > nums[1]) return 0;
        if (nums[n - 1] > nums[n - 2]) return n - 1;

        int l = 0, r = n - 1;
        while (l + 1 < r) {
            int m = l + (r - l) / 2;
            if (nums[m] < nums[m - 1]) {
                r = m;
            } else if (nums[m] < nums[m + 1]) {
                l = m;
            } else {
                return m;
            }
        }
        return -1;
    }
}

复杂度分析

时间复杂度:\(O(logn)\)\(n\) 表示数组长度。

空间复杂度:\(O(1)\)。只用到了有限个数的变量。

posted @ 2024-06-11 14:01  Sstarry  阅读(9)  评论(0)    收藏  举报