难度中等128
当 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
湍流子数组:↙↗↙↗↙↗
方法:滑动窗口
设数组 arr 的长度为 n,窗口 [left,right] (0≤left≤right≤n−1) 为当前的窗口,窗口内构成了一个「湍流子数组」。随后,我们要考虑下一个窗口的位置。
根据「湍流子数组」的定义,当 0<right<n-1 时:
如果 arr[right-1] < arr[right]且 arr[right] > arr[right+1],则 [left,right+1]也构成「湍流子数组」,因此需要将 right 右移一个单位;
如果 arr[right−1]>arr[right] 且 arr[right]<arr[right+1],同理,也需要将right 右移一个单位;
否则,[right−1,right+1] 无法构成「湍流子数组」,当left<right 时,[left,right+1] 也无法构成「湍流子数组」,因此需要将 left 移到 right,即令 left=right。
此外,我们还需要特殊考虑窗口长度为 1 (即 left 和 right 相等的情况):只要 arr[right] != arr[right+1],就可以将 right 右移一个单位;否则,left 和 right 都要同时右移。
class Solution {
public int maxTurbulenceSize(int[] arr) {
int n = arr.length;
int ret = 1;
int left = 0, right = 0;
while (right < n - 1) {
if (left == right) {
if (arr[left] == arr[left + 1]) {
left++;
}
right++;
} else {
if (arr[right - 1] < arr[right] && arr[right] > arr[right + 1]) {
right++;
} else if (arr[right - 1] > arr[right] && arr[right] < arr[right + 1]) {
right++;
} else {
left = right;
}
}
ret = Math.max(ret, right - left + 1);
}
return ret;
}
}