力扣练习之寻找峰值

我爱海鲸 2023-04-01 23:32:22 暂无标签

简介中级算法、排序和搜索

原题出处:https://leetcode.cn/leetbook/read/top-interview-questions-medium/xv4bbv/

解法一:

class Solution {
    public int findPeakElement(int[] nums) {
        return getResult(nums,0);
    }

    private int getResult(int[] nums,int index) {
        int firstValue = index == 0 ? Integer.MIN_VALUE  : nums[index-1];
        int mid = nums[index];
        int lastValue = index == nums.length -1 ? Integer.MIN_VALUE  : nums[index+1];

        if (firstValue < mid && mid > lastValue) {
            return index;
        }

        if (index == nums.length -1) {
            return 0;
        }

        return getResult(nums,index +1);
    }

}

思路:递归,我们定义三个变量,然后对比这三个变量,只需要中间的元素,大于第一个变量,小于第三个变量,那我们就把它的索引值返回即可,否则就将索引值加1进行递归。

解法二:

class Solution {
    public int findPeakElement(int[] nums) {
        int left = 0, right = nums.length - 1;
        while (left <= right) {
            int mid = (left + right) / 2;
            if ((mid == 0 || nums[mid] > nums[mid - 1]) && 
                (mid == nums.length - 1 || nums[mid] > nums[mid + 1])) {
                return mid;
            } else if (mid > 0 && nums[mid - 1] > nums[mid]) {
                right = mid - 1;
            } else {
                left = mid + 1;
            }
        }
        return -1;
    }
}

思路:

题目要求时间复杂度为 O(log n),因此可以考虑使用二分查找来解决。具体思路如下:

  • 初始化左右指针 left 和 right 分别指向数组的第一个元素和最后一个元素。

  • 进入循环,当 left 小于等于 right 时执行以下操作:

  • 计算中间位置 mid = (left + right) // 2。

  • 如果 mid 处于上升趋势,则峰值可能在 mid 右侧,因此将 left 更新为 mid + 1。

  • 如果 mid 处于下降趋势,则峰值可能在 mid 左侧,因此将 right 更新为 mid - 1。

  • 否则 mid 就是峰值,直接返回 mid。

  • 如果循环结束仍未找到峰值,返回 -1。

你好:我的2025