Leetcode : 162题解析(C++)

题目链接

题目解析

本题意在一个数组中找出一个峰值,这个题目用暴力求解也可以去做,方法就是将数组遍历一遍,然后找出其中一个峰值即可,但是其时间复杂度就会是O(n),而不是题目要求的O(logN)。

那我们就从另一个角度去分析该题,题目是让我们找到峰值,峰值的概念就是其左右元素都比它小。 然后我们在来分析峰值左右元素的规律,峰值的左侧元素一定是局部递增序列,峰值的右侧一定是局部递减序列,我们知道了这个规律后就可以使用变形的二分查找方法来找出峰值。

举例说明:
数组a[] = {1, 2, 3, 2, 5 ,6, 7, 2};
在该例子中,有两个峰值元素,3和7。分析该数字左右两侧的局部序列,发现左侧递增右侧局部递减。

如果a[mid] > a[mid + 1] (就是该元素比其右侧元素大,那就证明峰值是其本身或者在其左侧序列中)
如果a[mid] < a[mid + 1] (那就证明峰值肯定在其右侧序列,肯定不是a[mid])。
这两句话可以结合上面的规律好好理解
然后代码的分割点也找到之后,这道题就已经可以求解了。利用二分查找我们就可以将时间复杂度降到O(logn)

完整代码如下:

class Solution {
public:
    int findPeakElement(vector<int>& nums)
    {
        return find(nums, 0, nums.size() -1);
    } 
    int find(vector<int> &nums, int low, int high)
    {
        if(low == high)
            return low;
        int mid = (low + high) / 2;
        if(nums[mid] > nums[mid + 1])
        {
            return find(nums, low, mid);
        }
        return find(nums, mid + 1, high);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值