目录:
目的
[2,4,1,2,7,8,4], 峰值为1,4和8都是峰值元素,返回4的索引1或者8的索引5都可以。
思路
这个任务是找到数组中的峰值元素并返回其索引。假设你是一名探险家,来到了一片神秘的山脉。你的任务是找到其中的某个“山峰”(中间的山峰比两边的都高)并返回它的位置。你想快点爬到山峰打卡,所以采用一种高效的方法——二分查找。
进入山脉:
- 你站在山脉的起点,把起点标记为
left = 0
,终点标记为right = len(nums) - 1
,相当于说:“我要从山脉的左边走到右边,寻找最高的地方。” - 为了高效,你决定从当前范围的“中间”开始攀爬
mid
= left + (right - left) // 2。
判断方向:山势变化的线索:
当你站在
mid
点,向右边(mid + 1
)的方向看去:
- 如果 右边的山比你所在的山高,说明真正的峰值肯定在右侧,因为“山还没到顶”。所以你就挪动起点到
mid + 1
,继续从新的范围寻找。- 如果 右边的山比你所在的山低,说明峰值在你当前的位置或者左侧,因为“你可能已经接近峰值”。所以你就缩小终点到
mid
,逐步逼近峰值。
找到峰值:终点即答案
当 left
和 right
重合时,意味着你站在一个峰值的位置,因为没有更高的山势可以继续探索了。这时你就停下来说:“找到了!这里就是峰值。”
复杂度
-
时间复杂度:O(log n)
- 因为每次查找都将查找范围缩小一半。
-
空间复杂度:O(1)
- 只使用了常数级别的额外空间。
记忆秘诀
- 站中间:每次找到当前观察范围的中点
- 看两边:比较中间位置的值 与右边相邻的值。
- 右高往右:如果右侧更高,峰值一定在右侧。
- 左高靠左:如果左侧更高,峰值可能在当前或左侧。
- 指针相遇峰值现:指针重合即峰值的位置。
python代码
#
# 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
#
#
# @param nums int整型一维数组
# @return int整型
#
class Solution:
def findPeakElement(self, nums: List[int]) -> int:
left, right = 0, len(nums) - 1
while left < right:
mid = left + (right - left) // 2
# 如果 mid 的值小于 mid + 1 的值,则峰值必定在右侧
if nums[mid] < nums[mid + 1]:
left = mid + 1
else: # 否则,峰值可能在 mid 位置或者在左侧
right = mid
return left # left 和 right 会在同一位置相遇,即为峰值的索引
* 欢迎大家探讨新思路,能够更好的理解和记忆