二分查找实战:山峰数组峰顶索引与寻找峰值
在算法面试中,二分查找的应用远不止于简单的有序数组查找。当数据呈现某种特定的单调性或'二段性'时,我们依然可以利用二分思想来加速搜索。今天主要拆解两道基于二分查找的经典题目:山峰数组的峰顶索引和寻找峰值。
1. 山峰数组的峰顶索引
题目描述
给定一个长度为 n 的山脉数组 arr,其中存在某个索引 i (0 < i < n - 1) 满足:
- arr[0] < arr[1] < ... < arr[i]
- arr[i] > arr[i+1] > ... > arr[n-1]
我们需要找到这个峰顶索引 i。

解题思路
这道题的关键在于利用数组的单调性。虽然整个数组不是有序的,但我们可以将其视为两个有序部分:上升段和下降段。
观察中间位置 mid 与其相邻元素的关系:
- 如果
arr[mid] < arr[mid + 1],说明当前处于上升阶段,峰值一定在右侧(包含 mid+1)。 - 如果
arr[mid] > arr[mid + 1],说明当前处于下降阶段或已经是峰值,峰值一定在左侧(包含 mid)。
通过不断缩小搜索区间,最终 left 和 right 会收敛到同一个位置,即峰值索引。
C++ 实现
class Solution {
public:
int peakIndexInMountainArray(vector<int>& arr) {
int left = 0;
int right = arr.size();
while (left < right) {
// 使用向上取整避免死循环,确保 mid 偏向右侧
int mid = left + (right - left + 1) / 2;
// 比较 mid 与前一个元素,判断趋势
if (arr[mid - 1] < arr[mid]) {
// 上升趋势,峰值在右侧
left = mid;
} else {
// 下降趋势,峰值在左侧
right = mid - 1;
}
}
left;
}
};





