1. 题目链接:852. 山脉数组的峰顶索引
2. 题目描述:
符合下列属性的数组
arr称为 山脉数组 :
arr.length >= 3- 存在
i(0 < i < arr.length - 1)使得:
arr[0] < arr[1] < ... arr[i-1] < arr[i]
arr[i] > arr[i+1] > ... > arr[arr.length - 1]给你由整数组成的山脉数组
arr,返回满足arr[0] < arr[1] < ... arr[i - 1] < arr[i] > arr[i + 1] > ... > arr[arr.length - 1]的下标i。你必须设计并实现时间复杂度为
O(log(n))的解决方案。示例 1:
输入:arr = [0,1,0] 输出:1示例 2:
输入:arr = [0,2,1,0] 输出:1示例 3:
输入:arr = [0,10,5,2] 输出:1提示:
3 <= arr.length <= 105
0 <= arr[i] <= 106- 题目数据保证
arr是一个山脉数组
3. 解法2(暴力查找)
3.1 算法思路
峰顶的特点:比两侧的元素都要大
因此我们可以遍历数组中的每一个元素,找到某一个元素比两边的元素大即可
3.2 C++算法代码:
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;
        }
        return -1;
    }
};
4. 解法1(二分查找)
4.1 算法思路:
分析峰顶位置的数据特点,以及山峰两旁的数据的特点:
峰顶数据特点:arr[i]>arr[i-1] && arr[i]>arr[i+1]
- 峰顶左边的数据特点:arr[i]>arr[i-1] && arr[i]<arr[i+1],也就是呈现向上的趋势
- 峰顶右边的数据特点:arr[i]<arr[i-1] && arr[i]>arr[i+1],也就是呈现下降的趋势
根据mid位置的信息,我们可以分为下面三种情况:
- 如果mid位置呈现上升趋势,说明我们接下来要在[mid+1,right]区间继续搜索
- 如果mid位置呈现下降趋势,说明我们接下来要在[left,mid-1]区间搜索
- 如果mid位置就是山峰,直接返回结果

4.2 C++算法代码:
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;
          if(arr[mid]>arr[mid-1]) left=mid;
          else right=mid-1;
      }
      return left;
    }
};



















