852. 山脉数组的峰顶索引『简单』

题目来源于力扣(LeetCode

一、题目

852. 山脉数组的峰顶索引

题目相关标签:二分查找

说明:

  • 3 <= A.length <= 10000
  • 0 <= A[i] <= 10^6
  • A 是如上定义的山脉

二、解题思路

2.1 线性扫描方式

  1. 据题意:数组是一个确定为山脉的数组,即找到最大值既是顶峰

  2. 遍历数组 A,对于每一个元素都判断是否大于索引后一个元素,大于时,即是顶峰

2.2 二分查找法

  1. 使用二分查找方式,每次对一个计算得到的中间索引进行判断

  2. 3 种情况的判断

    1. 大于后一个元素时,既可能为顶峰,也可能为顶峰后的元素,右指针为中间索引 - 1

    2. 小于时,说明在顶峰之前,左指针为中间索引 + 1

    3. 大于后一个元素并且大于前一个元素时,即是顶峰

三、代码实现

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);
}
posted @ 2020-05-27 22:02  知音12138  阅读(263)  评论(0编辑  收藏  举报