难度:⭐
题目描述:
我们把符合下列属性的数组 A 称作山脉:
A.length >= 3
- 存在
0 < i < A.length - 1
使得A[0] < A[1] < ... A[i-1] < A[i] > A[i+1] > ... > A[A.length - 1]
给定一个确定为山脉的数组,返回任何满足 A[0] < A[1] < ... A[i-1] < A[i] > A[i+1] > ... > A[A.length - 1]
的 i
的值。
示例1:
1 | 输入:[0,1,0] |
示例2:
1 | 输入:[0,2,1,0] |
提示:
3 <= A.length <= 10000
- 0 <= A[i] <= 10^6
- A 是如上定义的山脉
解题过程:
思路:
山脉数组前半部分是递增的后半部分是递减的,就是要求出中间的那个最大的元素下标。
遍历数组,返回第一个元素值大于下个元素值的元素的下标。
c++代码:(执行用时20ms,击败86.50%,内存消耗11.8M,击败6.80%)
1 | class Solution { |
官方题解:
方法一:线性扫描
思路和算法
从左往右扫描直到山的高度不再增长为止,停止增长点就是峰顶。
Java代码:
1 | class Solution { |
复杂度分析
- 时间复杂度:$O(N)$,其中 N是
A
的长度。 - 空间复杂度:$O(1)$。
方法二:二分查找
思路和算法
将山脉数组中所有满足 A[i] < A[i+1]
的 i
点标记为 True
,不满足的点标记为 False
。则一个山脉数组可以标记为:[True, True, True, ..., True, False, False, ..., False]
。例如山脉数组 [1, 2, 3, 4, 1]
可以标记为 True, True, True, False
。
在山脉数组上使用二分查找,找出满足 A[i] < A[i+1]
的最大 i
。更多关于 二分查找 的知识,请访问 Leetcode 探索。
Java代码:
1 | class Solution { |
复杂度分析
- 时间复杂度:$O(\log N)$,其中 $N$ 是
A
的长度。 - 空间复杂度:$O(1)$。
总结:
官方题解提供了线性扫描和二分查找两种思路,线性扫描效率要高一些,二分查找也不失为一种方法。注意有的时候where循环比for循环更合适,注意where循环、for循环乃至do…while循环的使用条件。