二分查找实战:山脉数组的峰顶索引与寻找峰值
在算法面试中,二分查找的应用场景远不止于有序数组的查找。当数据具备某种单调性或二段性特征时,二分法同样能发挥奇效。本文通过两道经典题目——「山脉数组的峰顶索引」和「寻找峰值」,深入剖析如何利用二分查找高效定位局部极值。
021 山脉数组的峰顶索引
题目描述:

给定一个长度为 n 的山脉数组 arr,其中存在某个索引 i (0 < i < n - 1) 使得:
- arr[0] < arr[1] < ... < arr[i - 1] < arr[i]
- arr[i] > arr[i + 1] > ... > arr[n - 1]
我们需要找到这个峰顶索引 i。
思路一:暴力遍历
最直观的方法是遍历数组,检查每个元素是否大于其左右相邻的元素。由于题目保证是山脉数组,一旦找到满足条件的元素即可返回。
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;
}
};
时间复杂度: O(n),空间复杂度: O(1)。
虽然可行,但在数据量较大时效率较低。既然数组具有明显的上升和下降趋势,我们可以利用这一特性优化搜索过程。
思路二:二分查找
核心逻辑
观察山脉数组的特性,我们可以将数组分为两段:
- 上升段:
arr[mid] > arr[mid - 1],说明 mid 位于山峰左侧或就是山峰。 - 下降段:
arr[mid] < arr[mid - 1],说明 mid 位于山峰右侧。





