文章目录
- 题目描述
- 算法原理
- 解法一:暴力查找
- 解法二:二分查找
- 代码实现
- 暴力查找
- 二分——C++
- 二分——Java
题目描述
题目链接:852.山脉数组的峰顶索引
算法原理
解法一:暴力查找
峰顶:比左右区间都大
遍历整个数组,寻找数组内符合这个条件的元素即可。
解法二:二分查找
- 分析峰顶位置的数据特点,以及⼭峰两旁的数据的特点:
- 峰顶数据特点: 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 位置就是⼭峰,直接返回结果。
代码实现
暴力查找
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;}
};
二分——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;}
};
二分——Java
class Solution {public int peakIndexInMountainArray(int[] arr) {int left = 1, right = arr.length - 2;while (left < right) {int mid = left + (right - left + 1) / 2;if (arr[mid] > arr[mid - 1])left = mid;elseright = mid - 1;}return left;}
}