题目描述:
当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])
解题思路:
本题最容易想到的是两层for循环,但是题目给定A的长度最大40000,le9一定会超时。考虑到两层for循环是中的每一趟存在大量的重复计算,可以用动态规划在O(N)时间复杂度内求解。定义状态dp[i]是以A[i]结尾最长湍流子串。如果A[i]两侧比较符号不同,dp[i] = dp[i-1] + 1,否则dp[i] = 1
int maxTurbulenceSize(vector<int>& A) {
int maxl = INT_MIN,alle = 1;
int len = A.size();
if(len <= 1) return len;
int dp[len] = {0};
dp[0] = 1;
maxl = max(maxl,dp[0]);
char op = '=';
if(A[0] < A[1]) op = '<';
if(A[0] > A[1]) op = '>';
for(int i=1;i<len-1;i++){
char opt = '=';
if(A[i] < A[i+1]) opt = '<';
if(A[i] > A[i+1]) opt = '>';
if(opt != '='){
alle = 0;
if(op != opt){
dp[i] = dp[i-1] + 1;
maxl = max(maxl,dp[i]);
}
else dp[i] = 1;
op = opt;
}
}
return (alle == 1)?1:(maxl+1);
}