二分查找算法——山脉数组的峰顶索引&寻找峰值

1.题目解析

题目来源:852.山脉数组的峰顶索引

测试用例

题目来源:162.寻找峰值

测试用例

2.算法原理

山脉数组的峰顶索引 

根据二段性将山脉数组分为两段:上升段与下降段

1.当mid指针落入上升段,说明峰值在mid指针后,要从左边缩小范围,此时将mid给left

2.当mid指针落入下降段,说明峰值在mid指针前,需要从右边缩小范围,此时将mid-1给right即可

注意:由于在处理mid指针时出现了mid-1,则在初始化mid时需要使用left+(right-left+1)/2,而不是left+(right-left)/2,如果是mid+1则是第二种 

寻找峰值 

与前一道题相同但是多了一个条件:nums[0] = nums[n-1] = 负无穷

根据二段性将数组分为两段:上升段与下降段

1.当mid指针落入上升段,说明峰值在mid指针后,要从左边缩小范围,此时将mid给left

2.当mid指针落入下降段,说明峰值在mid指针前,需要从右边缩小范围,此时将mid-1给right即可

注意:由于在处理mid指针时出现了mid-1,则在初始化mid时需要使用left+(right-left+1)/2,而不是left+(right-left)/2,如果是mid+1则是第二种 

为什么可以直接确定峰值的位置在mid的那个位置呢?

因为由于山脚都是负无穷,如果mid在上升段那么即便数组一直处于上升那么最后一个元素也是峰值,相应的在下降段即便数组整体都是降序,那么第一个元素也是峰值,与其纠结上升段前可能会有峰值不如选择上升段后一定有峰值,下降段也是如此,大概可以理解为贪心 

3.实战代码

山脉数组的峰顶索引

class Solution {
public:
    int peakIndexInMountainArray(vector<int>& arr) 
    {
        int left = 1,right = arr.size() - 2;
        while(left < right)
        {
            int mid = left + (right - left + 1) / 2;
            //mid指针落入上升段,将左指针指向mid
            //从左边缩小范围
            if(arr[mid] >= arr[mid - 1])
            {
                left = mid;
            }
            //mid指针落入下降段,将右指针指向mid指针的前一个
            //从右边缩小范围
            else
            {
                right = mid - 1;
            }
        }
        return left;
    }
};

寻找峰值

class Solution {
public:
    int findPeakElement(vector<int>& nums) 
    {
        int left = 0,right = nums.size() - 1;
        while(left < right)
        {
            int mid = left + (right - left) / 2;
            //处于上升段,峰值在mid指针之后
            //从左边缩小范围
            if(nums[mid] < nums[mid + 1])
            {
                left = mid + 1;
            }
            //处于下降段,峰值在mid指针之前
            //从右边缩小范围
            else
            {
                right = mid;
            }
        }
        return left;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值