二分查找习题篇(下)

二分查找习题篇(下)

1.山脉数组的峰顶索引

题目描述:

给定一个长度为 n 的整数 山脉 数组 arr ,其中的值递增到一个 峰值元素 然后递减。

返回峰值元素的下标。

你必须设计并实现时间复杂度为 O(log(n)) 的解决方案。

示例 1:

输入:arr = [0,1,0]
输出:1

示例 2:

输入:arr = [0,2,1,0]
输出:1

示例 3:

输入:arr = [0,10,5,2]
输出:1

解法一:暴力枚举 O(N)

算法思路:

根据峰顶值的特点(比两侧元素都要大),遍历数组内的每一个元素,找到一个比左右两边元素都大的元素即可。

代码实现:
class Solution {
   
public:
    int peakIndexInMountainArray(vector<int>& arr) 
    {
   
        int n = arr.size();
        // 遍历数组内每⼀个元素,直到找到峰顶
        for (int i = 1; i < n - 1; i++) 
            // 峰顶满⾜的条件
            if (arr[i] > arr[i - 1] && arr[i] > arr[i + 1])
            	return i; 
        // 为了处理 oj 需要控制所有路径都有返回值
        return -1;
    }
};

解法二:二分查找算法

算法思路:

由题意我们可以将数组分为两部分,以峰顶值元素i为界,i左边区域是arr[i]>arr[i-1],i右边区域是arr[i]<arr[i-1]。即具有“二段性”,可以用二分查找。

算法流程:

1.令left=0,right=arr.size()-1;

2.当left<right时,下列一直循环:

找到待查找区间的中间点 mid ,找到之后分两种情况讨论:

  • arr[mid]>arr[mid-1],说明mid处于i的左边区域,更新left=mid;
  • arr[mid]<arr[mid-1],说明mid处于i的右边区域,更新
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值