75. 寻找峰值

题目描述

你给出一个整数数组(size为n),其具有以下特点:
相邻位置的数字是不同的
A[0] < A[1] 并且 A[n - 2] > A[n - 1]
假定P是峰值的位置则满足A[P] > A[P-1]且A[P] > A[P+1],返回数组中任意一个峰值的位置。

注意事项
It’s guaranteed the array has at least one peak.
The array may contain multiple peeks, find any of them.
The array has at least 3 numbers in it.

样例
给出数组[1, 2, 1, 3, 4, 5, 7, 6]返回1, 即数值 2 所在位置, 或者6, 即数值 7 所在位置.

分析
任意选取数组中的一个元素A[n](n!=0&&n!=A.length-1),一共可能出现四种情况:
1 A[n-1]< A[n],A[n+1]>A[n],即A[n]处在一个递增序列中。此时大于n的位置中必存在峰值。
2.A[n-1]> A[n],A[n+1]< A[n],即A[n]处在一个递减序列中。此时小于n的位置中必存在峰值。
3.A[n-1]> A[n],A[n+1] >A[n],即A[n]处在一个“低谷”,分析题目给定的数组的条件可知此时n左右两边都存在峰值。
4. A[n-1]< A[n],A[n+1]< A [n],此时n即我们要找的峰值。

经过以上分析,便可以用二分法简单的寻找到一个峰值。
另外,若数组中存在n个“低谷”,就会有n+1个峰值,二分搜索的过程中每次碰到低谷,在代码中只选择了其左边或右边一种情况,因此只能找到一个峰值。不过这已经满足题目要求。

代码

public class Main {
    public static int findPeak(int[] A) {
        // write your code here
        int l = 0;
        int r = A.length-1;
        int mid;
        while (l+1<r){
            mid = l+(r-l)/2;
            if (A[mid]>A[mid+1]&&A[mid]>A[mid-1]){
                return mid;
            }
            //A[mid]处在递增区间 l=mid+1
            if (A[mid]>A[mid-1]&&A[mid]<A[mid+1]){
                l=mid+1;
            }
            //A[mid]处在递减区间 r=mid-1
            if(A[mid]<A[mid-1]&&A[mid]>A[mid+1]){
                r=mid-1;
            }
            if (A[mid]<A[mid+1]&&A[mid]<A[mid-1]){
                l=mid+1;
            }
        }
        if (l>0&&A[l]>A[l+1]&&A[l]>A[l-1]){
            return l;
        }
        if (r<A.length-1&&A[r]>A[r+1]&&A[r]>A[r-1]){
            return r;
        }
        return -1;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值