动态规划解题步骤:
1.确定状态表示:dp[i]是什么
2.确定状态转移方程:dp[i]等于什么
3.初始化:确保状态转移方程不越界
4.确定填表顺序:根据状态转移方程即可确定填表顺序
5.确定返回值
题目链接: 978. 最长湍流子数组 - 力扣(LeetCode)
题解:
1.状态表示:dp[i]表示以arr[i]为结尾的最大湍流子数组的长度
2.状态转移方程:
求状态转移方程前,先理解:如果[a,b,c,d,e]是湍流子数组,[d,e,f]也是湍流子数组,那么[a,b,c,d,e,f]也是湍流子数组。即以元素e结尾的湍流子数组,如果其前一个元素d和后一个元素f组成的子数组也是湍流子数组,那么以元素f结尾的湍流子数组只需在以e结尾的湍流子数组基础上加上元素f即可。
dp[i]可以由dp[i-1]推出,如果arr[i]、arr[i-1]、arr[i-2]组成湍流子数组,那么dp[i-1]指向的湍流子数组再加上元素arr[i]也一定是一个湍流子数组;否则以arr[i]结尾的子数组一定没有长度超过2的湍流子数组(湍流子数组最小长度为2),此外还需要额外判断arr[i]和arr[i-1]是否相等,如果相等则以arr[i]结尾的子数组中不存在湍流子数组;如果不相等则最大湍流子数组长度为2
因此if((arr[i-2]<arr[i-1]&&arr[i-1]>arr[i])||(arr[i-2]>arr[i-1]&&arr[i-1]<arr[i])) dp[i]=dp[i-1]+1
else if(arr[i]!=arr[i-1]) dp[i]=2
else dp[i]=1
3.初始化:dp[0]=1
if(arr[0]!=arr[1]) dp[1]=2
4.填表顺序:从左向右,依次填写
5.返回值:返回dp表中的最大值
cpp
class Solution {
public:
int maxTurbulenceSize(vector<int>& arr) {
//dp[i]表示以arr[i]为结尾的最大湍流子数组的长度
//if((arr[i-2]<arr[i-1]&&arr[i-1]>arr[i])
//||(arr[i-2]>arr[i-1]&&arr[i-1]<arr[i]))
//dp[i]=dp[i-1]+1
//else if(arr[i]!=arr[i-1])dp[i]=2
//else dp[i]=1
//5<8>5<8>5 <8
//5<8>5<8>5 >1
//5<8>5<8>5 =5
//8>5<8>5<8 12
//a<b>c
//a>b<c
size_t n=arr.size();
//处理边界条件
if((n==1)||(n==2&&arr[0]==arr[1])) return 1;
if(n==2) return 2;
//创建dp表
vector<int> dp(n);
//初始化
dp[0]=1;
if(arr[0]!=arr[1]) dp[1]=2;
else dp[1]=1;
//填表
for(int i=2;i<n;++i)
{
if((arr[i-2]<arr[i-1]&&arr[i-1]>arr[i])
||(arr[i-2]>arr[i-1]&&arr[i-1]<arr[i]))
{
dp[i]=dp[i-1]+1;
}
else if(arr[i]!=arr[i-1]) dp[i]=2;
else dp[i]=1;
}
//返回值
int ans=INT_MIN;
for(auto e:dp) if(e>ans) ans=e;
return ans;
}
};