845. 数组中的最长山脉
题目描述
把符合下列属性的数组 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
,返回最长山脉子数组的长度。如果不存在山脉子数组,返回 0
。
示例 1:
输入:arr = [2,1,4,7,3,2,5] 输出:5 解释:最长的山脉子数组是 [1,4,7,3,2],长度为 5。
示例 2:
输入:arr = [2,2,2] 输出:0 解释:不存在山脉子数组。
提示:
1 <= arr.length <= 104
0 <= arr[i] <= 104
进阶:
- 你可以仅用一趟扫描解决此问题吗?
- 你可以用
O(1)
空间解决此问题吗?
解法
方法一:预处理 + 枚举
我们定义两个数组 \(f\) 和 \(g\),其中 \(f[i]\) 表示以 \(arr[i]\) 结尾的最长上升子序列的长度,而 \(g[i]\) 表示以 \(arr[i]\) 开头的最长下降子序列的长度。那么对于每个下标 \(i\),如果 \(f[i] \gt 1\) 且 \(g[i] \gt 1\),那么以 \(arr[i]\) 为山顶的山脉的长度为 \(f[i] + g[i] - 1\),我们只需要枚举所有的 \(i\),找出最大的那个值即可。
时间复杂度 \(O(n)\),空间复杂度 \(O(n)\)。其中 \(n\) 为数组 \(arr\) 的长度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
方法二:一次遍历(枚举左侧山脚)
我们可以枚举山脉的左侧山脚,然后向右寻找山脉的右侧山脚。我们可以使用两个指针 \(l\) 和 \(r\),其中 \(l\) 表示左侧山脚的下标,\(r\) 表示右侧山脚的下标,初始时 \(l=0\),\(r=0\),然后我们向右移动 \(r\),找到山顶的位置,此时判断 \(r\) 是否满足 \(r + 1 \lt n\) 并且 \(arr[r] \gt arr[r + 1]\),如果满足,我们向右继续移动 \(r\),直到找到右侧山脚的位置,此时山脉的长度为 \(r - l + 1\),我们更新答案,然后将 \(l\) 的值更新为 \(r\),继续寻找下一个山脉。
时间复杂度 \(O(n)\),空间复杂度 \(O(1)\)。其中 \(n\) 为数组 \(arr\) 的长度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
|