数组中的最长山脉
题目描述
我们把数组 A 中符合下列属性的任意连续子数组 B 称为 “山脉”:
B.length >= 3
- 存在
0 < i < B.length - 1
使得B[0] < B[1] < ... B[i-1] < B[i] > B[i+1] > ... > B[B.length - 1]
(注意:B 可以是 A 的任意子数组,包括整个数组 A。)
给出一个整数数组 A
,返回最长 “山脉” 的长度。
如果不含有 “山脉” 则返回 0
。
示例 1:
输入:[2,1,4,7,3,2,5] 输出:5 解释:最长的 “山脉” 是 [1,4,7,3,2],长度为 5。
示例 2:
输入:[2,2,2] 输出:0 解释:不含 “山脉”。
提示:
0 <= A.length <= 10000
0 <= A[i] <= 10000
方法一(动态规划)
解题思路
这题的做法可以想到 674.最长连续递增序列
dp1
: 从左到右记录以这个数为结尾的最长连续递增序列长度
dp2
: 从右到左记录以这个数为结尾的最长连续递增序列长度
最后遍历一遍统计 dp1[i] + dp2[i] - 1
为以这个数为山脉最高点的最长长度
nums = [2,1,4,7,3,2,5]
dp1 = [1,1,2,3,1,1,2]
dp2 = [2,1,1,3,2,1,1]
代码实现
class Solution:
def longestMountain(self, A: List[int]) -> int:
"""
方法一:使用动态规划的思想解决问题
"""
la = [0]*len(A)
lb = [0]*len(A)
for i in range(1, len(A)):
if A[i] > A[i-1]:
la[i] = la[i-1] + 1
for j in range(len(A)-1)[::-1]:
if A[j] >A[j+1]:
lb[j] = lb[j+1]+1
res = 0
for i in range(0, len(A)):
if la[i]>0 and lb[i]>0:
res = max(res, la[i]+lb[i]+1)
return res
方法二(标记法)
解题思路
使用两个变量 increasing
和 decreasing
,分别记录每个山脉上升区间的长度以及下降区间的长度。通过遍历,寻找最长的山脉。
遍历一遍数组,如果遇到连续递增的情况,那么 increasing
就加一;如果遇到连续递减的情况,那么 decreasing
就减一。
如果数组中只有一个山的话,那么遍历完一遍之后, increasing
和 decreasing
的和加一就是最后的结果。
为了防止一个数组中出现很多个山的情况,我们在每次的外循环使 increasing
和 decreasing
的值清零。
如果遇到相邻两元素值相同的情况,我们直接跳过即可。
代码实现
class Solution:
def longestMountain(self, A: List[int]) -> int:
"""
方法二:使用两个变量increasing和decreasing,分别记录每个山脉上升区间的长度以及下降区间的长度。通过遍历,寻找最长的山脉。
"""
maxLength = 0
j = 1
while j < len(A):
increasing, decreasing = 0, 0
while j < len(A) and A[j-1] < A[j]:
j += 1
increasing += 1
while j < len(A) and A[j-1] > A[j]:
j += 1
decreasing += 1
if increasing > 0 and decreasing > 0:
maxLength = max(maxLength, increasing + decreasing + 1)
while j < len(A) and A[j-1] == A[j]:
j += 1
return maxLength
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!