852. 山脉数组的峰顶索引『简单』
题目来源于力扣(LeetCode)
一、题目
题目相关标签:二分查找
说明:
3 <= A.length <= 10000
- 0 <= A[i] <= 10^6
- A 是如上定义的山脉
二、解题思路
2.1 线性扫描方式
-
据题意:数组是一个确定为山脉的数组,即找到最大值既是顶峰
-
遍历数组 A,对于每一个元素都判断是否大于索引后一个元素,大于时,即是顶峰
2.2 二分查找法
-
使用二分查找方式,每次对一个计算得到的中间索引进行判断
-
3 种情况的判断
-
大于后一个元素时,既可能为顶峰,也可能为顶峰后的元素,右指针为中间索引 - 1
-
小于时,说明在顶峰之前,左指针为中间索引 + 1
-
大于后一个元素并且大于前一个元素时,即是顶峰
-
三、代码实现
3.1 线性扫描方式
public static int peakIndexInMountainArray(int[] A) {
int i = 0;
for (; i < A.length; i++) {
// 题意说明:数组是一个确定为山脉的数组,即找到最大值既是顶峰
// 某个索引上的数大于索引后的数时,即是顶峰
if (A[i] > A[i + 1]) {
break;
}
}
return i;
}
3.2 二分查找法
public static int peakIndexInMountainArray(int[] A) {
int left = 0;
int right = A.length - 1;
while (left < right) {
// 中间索引
int mid = left + (right - left) / 2;
// 索引上的元素都大于前一个元素和后一个元素时,说明是顶峰
if (A[mid] > A[mid + 1] && A[mid] > A[mid - 1]) {
return mid;
}
else if (A[mid] > A[mid + 1]) {
// 当前索引上的元素大于右侧元素时,说明当前索引可能为顶峰
// 或在顶峰元素之后,缩小右边范围继续查找
right = mid - 1;
}
else if (A[mid] < A[mid + 1]) {
// 小于右侧元素时,说明在顶峰元素之前,缩小左边范围
left = mid + 1;
}
// 因为顶峰是存在的,所以不存在两个元素等于的情况
}
return left;
}
四、执行用时
4.1 线性扫描方式
4.2 二分查找法
五、部分测试用例
public static void main(String[] args) {
int[] A = {0, 1, 0}; // output:1
// int[] A = {0, 2, 1, 0}; // output:1
int result = peakIndexInMountainArray(A);
System.out.println(result);
}