寻找峰值
题目解析


题目给定一个数组,该数组并不像传统有序数组那样具有明显的二段性,可视为完全无序数组。目标是寻找满足大于左右两值的数的索引。暴力解法直接遍历数组,检查是否满足大于 i-1 和 i+1,时间复杂度为 O(N)。
虽然数组无序,但峰值条件(大于两边)隐含了局部单调性,可利用此条件使用二分查找优化。
算法原理
题目的隐含条件是左右两端可视作负无穷。数组存在二段性特征:

定义中间位置 mid,如果 arr[mid] > arr[mid + 1],则左区间一定存在答案(因为左侧是负无穷),可套用查找左端点的二分模板;同理,如果 arr[mid] < arr[mid + 1],代表右边有答案(右侧也是负无穷)。
算法编写
class Solution {
public:
int findPeakElement(vector<int>& nums) {
int left = 0, right = nums.size() - 1;
while(left < right) {
int mid = left + (right - left + 1) / 2;
if(nums[mid] > nums[mid - 1]) left = mid;
else right = mid - 1;
}
return left;
}
};
并非只有有序数组才存在二段性,完全无序的数组在特定条件下同样适用二分查找。








