二分查找实战:山峰数组峰顶索引与寻找峰值
在算法面试中,二分查找的应用场景非常广泛。除了传统的有序数组查找,它在处理具有特定单调性或二段性的结构时同样高效。今天我们来深入探讨两个经典题目:山脉数组的峰顶索引和寻找峰值元素。
21. 山脉数组的峰顶索引
题目描述
给定一个整数数组 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]
我们需要找到这个峰顶索引 i。
解题思路
这道题的核心在于利用数组的'二段性'。虽然整个数组不是有序的,但相对于峰顶位置,它具有明显的单调特征:
- 左侧:严格递增(
arr[mid] < arr[mid + 1]) - 右侧:严格递减(
arr[mid] > arr[mid + 1])
我们可以将问题转化为寻找第一个不满足递增条件的位置,或者更直观地,通过比较中间值与其右侧邻居的大小关系来缩小搜索范围。
如果 arr[mid] < arr[mid + 1],说明我们处于上升阶段,峰顶一定在 mid 的右侧(包含 mid + 1),因此左边界更新为 mid + 1。
如果 arr[mid] > arr[mid + 1],说明我们处于下降阶段或就在峰顶,峰顶在 mid 或其左侧,右边界更新为 mid。
这种写法通常采用左闭右开区间 [left, right),最终 left 即为所求索引。
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 + ;
} {
right = mid;
}
}
left;
}
};


