LeetCode.852 山脉数组的峰顶索引

558 阅读1分钟

「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战」。

题目描述:

852. 山脉数组的峰顶索引 - 力扣(LeetCode) (leetcode-cn.com)

符合下列属性的数组 arr 称为 山脉数组

  • arr.length >= 3
  • 存在 i(0 < i < arr.length - 1)使得:
    • arr[0] < arr[1] < ... arr[i-1] < arr[i]
    • arr[i] > arr[i+1] > ... > arr[arr.length - 1]

给你由整数组成的山脉数组 arr ,返回任何满足 arr[0] < arr[1] < ... arr[i - 1] < arr[i] > arr[i + 1] > ... > arr[arr.length - 1] 的下标 i

示例一

输入: arr = [0,1,0]
输出: 1

示例二

输入: arr = [0,2,1,0]
输出: 1

示例三

输入: arr = [0,10,5,2]
输出: 1

示例四

输入: arr = [3,4,5,1]
输出: 2

示例五

输入: arr = [24,69,100,99,79,78,67,36,26,19]
输出: 2

提示:

  • 3 <= arr.length <= 10^4
  • 0 <= arr[i] <= 10^6
  • 题目数据保证 arr 是一个山脉数组

思路分析

遍历

题目拟的很形象,我们如果把数组的下标作为x,值作为y,将数组添加到坐标系中,那这个数组呈现的样子就是一个山峰的形状,简单来说就是前一段递增,然后下一段递减,而题目要求的峰顶索引,其实就是找数组中最大的值。

这个就很简单了,我们只需要遍历一遍即可。

当我们遍历到下标 ii 时,如果有 arri1<arri>arri+1\textit{arr}_{i-1} < \textit{arr}_i > \textit{arr}_{i+1},那么 ii 就是我们需要找出的下标。

这里还可以优化下,我们的峰顶,之前一直是递增的,这不知道递增到什么时候,但是到了峰顶之后,下一个一定是递减的,所以我们只需要找到 i 满足 arri>arri+1\textit{arr}_i > \textit{arr}_{i+1}即可。

AC代码

class Solution {
    fun peakIndexInMountainArray(arr: IntArray): Int {
        var ans = -1
        for(i in 0..arr.size-1) {
            if(arr[i] > arr[i+1]) {
                ans = i
                break
            }
        }
        return ans
    }
}

二分查找

由之前分析可知,峰顶元素为全局最大值,所以我们很自然的想到可以使用二分法来查找。

AC代码

class Solution {
    fun peakIndexInMountainArray(arr: IntArray): Int {
        var left = 0
        var right = arr.size - 1

        while (left < right) {
            val mid = (left + right + 1) ushr 1
            if (arr[mid - 1] > arr[mid]) {
                right = mid - 1
            } else {
                left = mid
            }
        }
        return left
    }
}

总结

题目花里胡哨的,其实就是返回最大值的索引,或者找到最大值即可。

参考

山脉数组的峰顶索引 - 山脉数组的峰顶索引 - 力扣(LeetCode) (leetcode-cn.com)

852. Peak Index in a Mountain Array 山脉数组的峰顶索引 - 山脉数组的峰顶索引 - 力扣(LeetCode) (leetcode-cn.com)