162. 寻找峰值
寻找峰值
峰值元素是指其值严格大于左右相邻值的元素。
给你一个整数数组 nums
,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。
你可以假设 nums[-1] = nums[n] = -∞
。
你必须实现时间复杂度为 O(log n)
的算法来解决此问题。
示例 1:
输入:nums = [1,2,3,1]
输出:2
解释:3 是峰值元素,你的函数应该返回其索引 2。
示例 2:
输入:nums = [1,2,1,3,5,6,4]
输出:1 或 5
解释:你的函数可以返回索引 1,其峰值元素为 2;
或者返回索引 5, 其峰值元素为 6。
思路
要在时间复杂度为 O(logn)O(logn) 的条件下解决这个问题,我们可以使用二分查找算法。考虑到数组可能包含多个峰值,但只需要返回其中任何一个峰值的索引,可以通过二分查找来优化搜索过程。
题目分析:
- 峰值元素是指其值严格大于左右相邻值的元素。
- 如果我们发现
nums[mid] > nums[mid + 1]
,那么峰值一定在mid
左边(包括mid
)。 - 如果我们发现
nums[mid] < nums[mid + 1]
,那么峰值一定在mid
右边。
通过这种方式,二分查找能够将搜索空间缩小一半,因此时间复杂度为 O(logn)O(logn)。
class Solution {
public int findPeakElement(int[] nums) {
int n = nums.length;
int left = 0, right = n - 1;
while(left < right){
int mid = left + (right - left) / 2;
if(nums[mid] > nums[mid + 1]) {
right = mid;
}else{
left = mid + 1;
}
}
return left;
}
}
解释一下:
局部最大趋势:
- 如果
nums[mid] < nums[mid + 1]
,说明nums[mid + 1]
比nums[mid]
大,意味着当前mid
位置还不是一个峰值,且峰值应该位于右边。这是因为峰值是局部最大的元素,如果右边的元素更大,那么峰值必然在右侧。所以我们可以把left
移动到mid + 1
,从而缩小搜索区间,继续在右半部分查找峰值。 - 如果
nums[mid] > nums[mid + 1]
,说明nums[mid]
可能是一个局部峰值,因为左边的元素比右边的元素大。在这种情况下,峰值可能就在mid
或者它的左侧,因此我们将right
设置为mid
,继续在左半部分查找。
这里有个点注意:如果第一种情况, mid 位置不是峰值,自然下一次就不将其纳入我们需要搜索的范围之中去,所以我们写 left = mid + 1
;如果是第二种情况, mid 处可能是峰值,意味着下一次我们还是要将其纳入到我们搜索的范围当中去,所以我们写right = mid
。二分法工作的区间是[left,right]的一个闭区间。
本文作者:Drunker•L
本文链接:https://www.cnblogs.com/drunkerl/p/18646225
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步