leetcode 162. Find Peak Element

本文探讨了在数组中寻找峰值元素的问题,峰值元素定义为大于其邻居的元素。文章提供了两种解决方案:线性扫描和二分查找,并详细解释了二分查找在非完全有序数组中的应用,强调了二分法在每一步都能有效缩小搜索范围的优势。

A peak element is an element that is greater than its neighbors.

Given an input array nums, where nums[i] ≠ nums[i+1], find a peak element and return its index.

The array may contain multiple peaks, in that case return the index to any one of the peaks is fine.

You may imagine that nums[-1] = nums[n] = -∞.

Example 1:

Input: nums = [1,2,3,1]
Output: 2
Explanation: 3 is a peak element and your function should return the index number 2.

Example 2:

Input: nums = [1,2,1,3,5,6,4]
Output: 1 or 5
Explanation: Your function can return either index number 1 where the peak element is 2,
or index number 5 where the peak element is 6.

tag:array, binary search

method 1

线性扫描,遍历每一个数,比较是否左边的数要低一点,右边的数要高一点。

当然,如果发现右边的数要低一点,就没有必要再看右边的数是否符合,直接看右边的数的下一个数

public int findPeakElement(int[] nums) {
    for (int i = 1; i < nums.length-1; i++) {
        if (nums[i] > nums[i+1]){
            if (nums[i] > nums[i-1])
                return i;
            else i++;
        }
    }

    return 0;
}

method 2 binary search

这样的题使用二分查找,一开始还是很惊奇的,因为印象中都是对有序数组才使用二分法,但这是对二分法的误解,要理解二分法的精髓在于在每一步都减少待搜索的区间

考虑本题,一个数mid根据和其右边的数进行比较,可以得到该数是在下降的斜坡上还是在上升的斜坡,如果右边的数更小,可以认为是在下降的斜坡上,那么峰值一定是在mid的左边(包含其本身);如果右边的数更大,可以认为是在上升的斜坡上,那么峰值一定是在mid的右边,所以搜索范围可以限制在mid及其右边的子数组

public int findPeakElement(int[] nums) {
        int l = 0, r = nums.length - 1;
        while (l < r) {
            int mid = (l + r) / 2;
            if (nums[mid] > nums[mid + 1])
                r = mid;
            else
                l = mid + 1;
        }
        return l;
    }

当然,比如右边的数比mid更大,是在上升的斜坡中,将舍弃mid左边的子数组中也可能存在peak元素,但本题不是求最大的数,本题只要求找到一个peak即可,甚至边界值(i=0,i=n-1)也算peak,所以才可以这样使用二分法

summary:

  1. 使用二分法减少搜索空间
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值