「这是我参与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^40 <= arr[i] <= 10^6- 题目数据保证
arr是一个山脉数组
思路分析
遍历
题目拟的很形象,我们如果把数组的下标作为x,值作为y,将数组添加到坐标系中,那这个数组呈现的样子就是一个山峰的形状,简单来说就是前一段递增,然后下一段递减,而题目要求的峰顶索引,其实就是找数组中最大的值。
这个就很简单了,我们只需要遍历一遍即可。
当我们遍历到下标 ii 时,如果有 ,那么 ii 就是我们需要找出的下标。
这里还可以优化下,我们的峰顶,之前一直是递增的,这不知道递增到什么时候,但是到了峰顶之后,下一个一定是递减的,所以我们只需要找到 i 满足 即可。
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)