[优选算法专题三.二分查找——NO.21山脉数组的峰顶索引]
题目链接:
852. 山脉数组的峰顶索引
题目描述:
题目解答:
- 初始化指针:
int left = 1, right = arr.size() - 2;
初始化左右指针,因为山脉数组的峰值不可能是数组的第一个和最后一个元素,所以left
从 1 开始,right
从arr.size() - 2
开始。 - 二分查找循环:
while (left < right)
是二分查找的循环条件,当left
小于right
时,说明查找范围仍然存在,继续循环。 - 计算中间位置:
int mid = left + (right - left + 1) / 2;
计算中间位置mid
,(right - left + 1) / 2
这样计算可以确保在left
和right
较大时,不会出现整数溢出的问题,并且在left
和right
差值为 1 时,mid
会取到right
的值。 - 更新指针:如果
arr[mid] >= arr[mid - 1]
,说明mid
位置可能是峰值或者仍处于山脉数组的上升阶段,峰值在mid
及其右侧,所以将left
更新为mid
;否则,说明mid
处于山脉数组的下降阶段,峰值在mid
的左侧,将right
更新为mid - 1
。 - 返回结果:循环结束后,
left
和right
相等,它们指向的位置就是峰值索引,代码中return right
和return left
效果相同,因为此时二者相等。
例如,对于数组arr = {0, 1, 2, 3, 2, 1, 0}
,初始时left = 1
,right = 5
,第一次循环mid = 3
,arr[3] >= arr[2]
,则left
更新为 3;第二次循环mid = 4
,arr[4] < arr[3]
,则right
更新为 3,此时left == right
,循环结束,返回 3,即峰值索引。