【LeetCode题解】LeetCode 162. 寻找峰值
【题目链接】
162. 寻找峰值
【题目描述】
【题解】
峰值元素定义为严格大于左右相邻值的元素,且题目给定边界条件nums[−1]=nums[n]=−∞nums[-1] = nums[n] = -∞nums[−1]=nums[n]=−∞。这一条件至关重要:它保证了数组中至少存在一个峰值(即使数组严格递增,最后一个元素因右侧是−∞-∞−∞成为峰值;严格递减则第一个元素因左侧是−∞-∞−∞成为峰值)。
由于要求时间复杂度为O(logn)O(log n)O(logn),需用二分查找缩小区间。核心逻辑是:通过比较中间位置mmm和右侧邻居m+1m+1m+1的值,判断峰值的大致方向:
- 若nums[m]>nums[m+1]nums[m] > nums[m+1]nums[m]>nums[m+1]:
说明mmm处于下坡段(或本身是峰值)。由于左侧边界是−∞-∞−∞,从mmm向左必然存在一个峰值(即使左侧一直递减,最左端因左侧是−∞-∞−∞也会成为峰值)。因此,缩小右边界到mmm。 - 若nums[m]<nums[m+1]nums[m] < nums[m+1]nums[m]<nums[m+1]:
说明mmm处于上坡段。由于右侧边界是−∞-∞−∞,从m+1m+1m+1向右必然存在一个峰值(即使右侧一直递增,最右端因右侧是−∞-∞−∞也会成为峰值)。因此,缩小左边界到m+1m+1m+1。
【AC代码】
class Solution {
public:int findPeakElement(vector<int>& nums) {int l = 0, r = nums.size() - 1;while(l < r) {int mid = l + r >> 1;if(nums[mid] > nums[mid + 1])r = mid;elsel = mid + 1;}return l;}
};
【思考&收获】
二分算法的两类模板需要熟练掌握,但核心关键在于设计合理的checkcheckcheck函数,它直接定义了“如何根据中间位置的特征,判断下一阶段的搜索方向”。由于每道题的场景逻辑不同,真正的破题点永远是 结合问题条件,分析区间的“可二分性”,而非机械套用模板。