Question
当 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 的最大湍流子数组的长度。
Example 1:
输入:[9,4,2,10,7,8,8,1,9] 输出:5 解释:(A[1] > A[2] < A[3]
> A[4] < A[5])
Example 2:
输入:[4,8,12,16] 输出:2
提示:
1 <= A.length <= 40000
0 <= A[i] <= 10^9
Approach 1: 滑动窗口法
本题目需要仔细考虑清楚集中边界条件的情况:
左右边界相等;
右边界元素等于右边界+1元素;
右边界什么时候右移
左边界什么时候右移,移动到哪个位置
通过令边界left=right=0,设计一个滑动窗口,
当左右边界相等时,此时子数组只包含一个元素,肯定是可以右边界右移的;
当左右边界不相等时,如果右边界-1的元素、右边界元素、右边界+1的元素,三者满足 或者 时,右边界右移;
当左右边界不相等时,如果右边界-1的元素、右边界元素、右边界+1的元素,三者不满足 或者 ,则结束判断,left边界从right边界重新开始判断下一个子数组
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 26 27 28 29 30 31 32 33 34 class Solution : def maxTurbulenceSize (self, arr ) -> int : n = len (arr) res = 1 left,right=0 ,0 while (right<n-1 ): if left == right: if arr[right] == arr[right+1 ]: left+=1 right+=1 else : if (arr[right - 1 ] < arr[right]) and (arr[right] > arr[right + 1 ]): right+=1 elif (arr[right - 1 ] > arr[right]) and (arr[right] < arr[right + 1 ]): right+=1 else : left = right res = max (res, right - left + 1 ) return res def main (): inputs = [9 ,4 ,2 ,10 ,7 ,8 ,8 ,1 ,9 ] solution=Solution().maxTurbulenceSize(inputs) print (solution) if __name__ == "__main__" : main()
复杂度分析
时间复杂度: ,窗口的左右端点最多各移动 n
次。
空间复杂度: ,只需要维护常数额外空间。
Approach 2: 动态规划方法
也可以使用动态规划的方法计算最长湍流子数组的长度。
利用二维数组记录相邻元素的信息:
表示以arr[i]为结尾的,且 的湍流子数组的最大长度。
表示以arr[i]为结尾的,且 的湍流子数组的最大长度。
每次记录湍流子数组应该从1开始,因为需要包含自身。 - 当 时,湍流子数组长度为 ,同时 - 当 时,湍流子数组长度为 ,同时 - 当 时,湍流子数组长度为 最终, 数组的最大值即为所求的答案。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 def maxTurbulenceSize1 (self, arr ) -> int : n = len (arr) dp = [[0 for i in range (2 )] for j in range (n)] dp[0 ][0 ] = dp[0 ][1 ] = 1 for i in range (n): if arr[i-1 ] > arr[i]: dp[i][0 ] = dp[i-1 ][1 ] + 1 dp[i][1 ] = 1 elif arr[i-1 ] < arr[i]: dp[i][1 ] = dp[i-1 ][0 ] + 1 dp[i][0 ] = 1 else : dp[i][0 ] = dp[i][1 ] = 1 res = 1 for i in range (n): res = max (res, dp[i][0 ]) res = max (res, dp[i][1 ]) return res
复杂度分析
时间复杂度: ,遍历一遍数组。
空间复杂度: ,只需要维护dp。
其实还可以直接用两个变量 和 代替二维数组dp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 def maxTurbulenceSize2 (self, arr ) -> int : n = len (arr) res = 1 dp0 = dp1 = 1 for i in range (1 ,n): if arr[i-1 ] > arr[i]: dp0 = dp1 + 1 dp1 = 1 elif arr[i-1 ] < arr[i]: dp1 = dp0 + 1 dp0 = 1 else : dp0 = dp1 = 1 res = max (res, dp0) res = max (res, dp1) return res
复杂度分析
时间复杂度: ,遍历一遍数组。
空间复杂度: ,只需要维护dp0和dp1两个变量。