二分查找实战:山峰数组峰顶索引与寻找峰值
在算法面试中,利用单调性进行二分查找是高频考点。今天我们来深入探讨两个经典问题:山脉数组的峰顶索引(LeetCode 852)和寻找峰值(LeetCode 162)。这两个问题虽然场景不同,但核心都在于识别数据的'二段性'。
1. 山峰数组的峰顶索引
题目描述: 给定一个长度为 n 的山脉数组 arr,其中存在唯一的峰顶索引 i,满足: arr[0] < arr[1] < ... < arr[i] > arr[i+1] > ... > arr[n-1] 请返回该峰顶索引。
题目示例:

解法思路: 这道题的关键在于利用数组的单调性。峰顶左侧严格递增,右侧严格递减。我们可以将搜索区间划分为两部分:一部分满足'上升'条件,另一部分满足'下降'或'到达峰值'条件。
具体判断逻辑如下:
- 如果
mid位置的值小于其右侧相邻值 (arr[mid] < arr[mid + 1]),说明我们处于上升坡段,峰顶一定在右侧(包含 mid+1),因此左边界移动至mid + 1。 - 如果
mid位置的值大于等于其右侧相邻值,说明我们已经到达或越过峰顶,或者处于下降坡段,此时右边界收缩至mid。
注意处理整数溢出问题,计算中间值时使用 left + (right - left) / 2。
C++ 代码实现:
class Solution {
public:
int peakIndexInMountainArray(vector<int>& arr) {
int left = 0;
int right = arr.size();
while(left < right) {
int mid = left + (right - left) / 2;
// 如果当前值小于右边,说明在爬坡,峰顶在右侧
if(arr[mid] < arr[mid + 1]) {
left = mid + 1;
} else {
// 否则在山顶或下坡,峰顶在左侧(含 mid)
right = mid;
}
}
return left;
}
};
流程解析:





