双指针解法
思路:如果left-right 满足湍 流子数组,则right 向右移动, 判断是否满足新的湍流子数组的概念,具体判断方法:在右移之前需要标记 right 与right-1 的大小, 如过前者大,则flag=1,表示进入窗口的元素要小于当前的末尾(即right),反之表示进入的窗口数据增大
class Solution {
public:
int maxTurbulenceSize(vector<int>& arr) {
int left=0;
int right=1;
int res=1;
while(right<arr.size()){
int flag=1; // 表示减小
if(arr[right]>arr[left]) flag=0;
if(arr[right]==arr[left]){left=right,right=left+1;}
//主体函数
while(right<arr.size()){ //假设left-right-1 已是湍流子数组
if(arr[right]==arr[right-1]) break; //到达这里,说明当前的以left开头的湍流子数组达到最长
if(flag==1 && arr[right]<arr[right-1])//flag=1 表示进入窗口的元素要小于当前的末尾
flag=0;// 下一次进入窗口的元素要大于窗末的元素
else if( flag==0 && arr[right]>arr[right-1])
flag=1;
else break;
right++;
}
res=max(res,right-left);
left=right-1;
right=left+1;
}
return res;
}
};
动态规化解题思路:
dp[i] 表示以i开头的湍流数组的最长的长度,求出dp[i], 遍历每个开头求最大值,或者在求dp 过程中维护最大值
- 如果i为最后一个元素,则 dp[i]=1;
- 如果i为倒数第二个元素,则dp[i]至少为1(两元素相等), 如果最后两个元素不相等, 则dp[i]=2
- j从倒数第三个开始到第0个元素
1) 如果nums[j]==nums[j+1] dp[j]=1
2)如果 nums[j]>nums[j+1] && nums[j+1]<nums[j+2] 或如果 nums[j]<nums[j+1] && nums[j+1]>nums[j+2] dp[j]=dp[j+1]+1;
3)其他(nums[j],nums[j+1],nums[j+2],递增或递减 如 7,8,9(以7为开头的最长为2)) dp[j]=2
class Solution {
public:
int maxTurbulenceSize(vector<int>& arr) {
if(arr.size()<=1) return arr.size();
vector<int>dp(arr.size());
dp[arr.size()-1]=1;
dp[arr.size()-2]= arr[0]==arr[1] ? 1:2; // 最后两个元素相等为一,不等为二
for(int i=arr.size()-3;i>=0;i--){
if(arr[i]==arr[i+1]) dp[i]=1;
else if(arr[i]<arr[i+1] && arr[i+1]>arr[i+2] || arr[i]>arr[i+1] && arr[i+1]<arr[i+2])
dp[i]=1+dp[i+1];
else
dp[i]=2;
}
// 遍历每个开头求最大值,或者在求dp 过程中维护最大值
int res=0;
for(int i=0;i<arr.size();i++){
res=max(res, dp[i]);
}
return res;
}
};
// 空间压缩
class Solution {
public:
int maxTurbulenceSize(vector<int>& arr) {
if(arr.size()<=1) return arr.size();
int dp= arr[0]==arr[1] ? 1:2;//如果最后两个元素不相等, 则dp[i]=2 ,否则为1
int res=dp;//在求dp 过程中维护最大值
for(int i=arr.size()-3;i>=0;i--){
if(arr[i]==arr[i+1]) dp=1;
else if(arr[i]<arr[i+1] && arr[i+1]>arr[i+2] || arr[i]>arr[i+1] && arr[i+1]<arr[i+2])
dp=1+dp;
else
dp=2;
res=max(res,dp);
}
return res;
}
};