一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情。
符合下列属性的数组 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 。
示例 1:
输入:arr = [0,1,0]
输出:1
示例 2:
输入:arr = [0,2,1,0]
输出:1
示例 3:
输入:arr = [0,10,5,2]
输出:1
示例 4:
输入:arr = [3,4,5,1]
输出:2
示例 5:
输入:arr = [24,69,100,99,79,78,67,36,26,19]
输出:2
提示:
- 题目数据保证
arr
是一个山脉数组
枚举
我们可以对数组 arr\textit{arr}arr 进行一次遍历。
当我们遍历到下标 iii 时,如果有 ,那么 iii 就是我们需要找出的下标。
更简单地,我们只需要让 满足 即可。在遍历的过程中,我们最先遍历到的满足 的下标 i 一定也满足 。
var peakIndexInMountainArray = function(arr) {
const n = arr.length;
let ans = -1;
for (let i = 1; i < n - 1; ++i) {
if (arr[i] > arr[i + 1]) {
ans = i;
break;
}
}
return ans;
};
复杂度分析
- 时间复杂度:O(n),其中 n 是数组 arr 的长度。我们最多需要对数组 arr 进行一次遍历。
- 空间复杂度:O(1)。
二分查找
记满足题目要求的下标 i 为 。我们可以发现:
- 当 时, 恒成立;
- 当 时, 恒成立。
这与方法一的遍历过程也是一致的,因此 即为「最小的满足 的下标 i,我们可以用二分查找的方法来找出 。
var peakIndexInMountainArray = function(arr) {
const n = arr.length;
let left = 1, right = n - 2, ans = 0;
while (left <= right) {
const mid = Math.floor((left + right) /2 );
if (arr[mid] > arr[mid + 1]) {
ans = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
return ans;
};
复杂度分析
- 时间复杂度:,其中 n 是数组 的长度。我们需要进行二分查找的次数为 。
- 空间复杂度:O(1)。