难度:★★★☆☆
类型:数组
方法:动态规划
题目
力扣链接请移步本题传送门
更多力扣中等题的解决方案请移步力扣中等题目录
当 A 的子数组 A[i], A[i+1], ..., A[j] 满足下列条件时,我们称其为湍流子数组:
若 i <= k < j,当 k 为奇数时, A[k] > A[k+1],且当 k 为偶数时,A[k] < A[k+1];
或 若 i <= k < j,当 k 为偶数时,A[k] > A[k+1] ,且当 k 为奇数时, A[k] < A[k+1]。
也就是说,如果比较符号在子数组中的每个相邻元素对之间翻转,则该子数组是湍流子数组。
返回 A 的最大湍流子数组的长度。
示例 1:
输入:[9,4,2,10,7,8,8,1,9]
输出:5
解释:(A[1] > A[2] < A[3] > A[4] < A[5])
示例 2:
输入:[4,8,12,16]
输出:2
示例 3:
输入:[100]
输出:1
提示:
1 <= A.length <= 40000
0 <= A[i] <= 10^9
解答
这道题又是满足某条件的最大子序列的问题,可以选择双指针法(也就是滑动窗口法)或动态规划来解决。这里我们选择动态规划。
根据题目的定义,我们更形象的叫做波浪子数组。
【数组定义】
这里需要定义两个数组,他们的长度和输入的数组arr一致:
up:结尾上升数组。up[i]表示以i位置并以上升态势结尾的最长波浪子数组的长度。
down:结尾下降数组。up[i]表示以i位置并以下降态势结尾的最长波浪子数组的长度。
【初始状态】
因为波浪子数组至少含有一个元素,或者说函数的返回值至少是1,因此我们把up数组和down数组中每个位置都初始化为1。
【递推公式】
这里需要注意的是,up数组与down数组是有条件交互的,信息存在着某种程度的共享。
每当遇到arr[i-1]<arr[i]时,说明已经形成了以上升态势结尾的波浪,需要将这个小的上升波浪加入到以结尾态势结尾的相邻的波浪中,也就是up[i] = down[i - 1] + 1,
同样的,如果arr[i - 1] > arr[i],需要更新以下降态势结尾的波浪的长度down[i] = up[i - 1] + 1
【返回值】
一次遍历结束后,我们得到的数组up和down中已经存储了所有波浪数组的长度,合并后选择其中最大值就好。
可能还有一个疑惑,一旦遍历过程中波浪断掉了,比如遇到了连续的上涨或下降,或者平的波浪,还能按照这样的递推公式吗。答案是肯定的,因为我们在up和down数组中存储了初始值1,一旦波浪断掉,则还没有被使用过的1一定会被用起来,波浪长度会做重新的统计。
class Solution:
def maxTurbulenceSize(self, arr):
up, down = [1 for _ in arr], [1 for _ in arr]
for i in range(1, len(arr)):
if arr[i - 1] < arr[i]:
up[i] = down[i - 1] + 1
elif arr[i - 1] > arr[i]:
down[i] = up[i - 1] + 1
return max(max(up), max(down))
如有疑问或建议,欢迎评论区留言~
有关更多力扣中等题的python解决方案,请移步力扣中等题解析
网友评论