LC 162. 寻找峰值
LC 162. 寻找峰值
题目链接
题目思路
-
判断数组第一个元素和最后一个元素的上升下降趋势,如果
nums[0] > nums[1],0 就是峰值。如果nums[n - 1] > nums[n - 2],n - 1 就是峰值。 -
如果
nums[0]和nums[n - 1]均不是峰值。从nums[0]到nums[1]是 ↗ 的。从nums[n - 2]到nums[n - 1]是 ↘ 的。根据罗尔定理,在nums[1, n - 2]之间一定存在峰值。可以通过不断的二分查找,找到这个峰值。 -
通过比较数组中间元素
nums[m]的值和nums[m - 1]、nums[m + 1]值的大小来决定下次二分的范围。nums[m] < nums[m - 1]。nums[0]到nums[1]是 ↗ 的,nums[m - 1]到nums[m]是 ↘ 的,因此,峰值在左半部分[1, m - 1]。nums[m] < nums[m + 1]。nums[m]到nums[m + 1]是 ↗ 的,nums[n - 2]到nums[n - 1]是 ↘ ,因此,峰值在左半部分 [m + 1, n - 2]。
-
最后,一定能二分到
nums[m],满足nums[m - 1] < nums[m]和nums[m] > nums[m + 1]均成立,m 就是峰值下标。返回即可

题目代码
class Solution {
public int findPeakElement(int[] nums) {
int n = nums.length;
if (n == 1) return 0;
if (nums[0] > nums[1]) return 0;
if (nums[n - 1] > nums[n - 2]) return n - 1;
int l = 0, r = n - 1;
while (l + 1 < r) {
int m = l + (r - l) / 2;
if (nums[m] < nums[m - 1]) {
r = m;
} else if (nums[m] < nums[m + 1]) {
l = m;
} else {
return m;
}
}
return -1;
}
}
复杂度分析
时间复杂度:\(O(logn)\)。\(n\) 表示数组长度。
空间复杂度:\(O(1)\)。只用到了有限个数的变量。

浙公网安备 33010602011771号