个人主页:元清加油_【C++】,【C语言】,【数据结构与算法】-CSDN博客
个人专栏
力扣递归算法题
【C++】
http://t.csdnimg.cn/6AbpV
数据结构
前言:这个专栏主要讲述动态规划算法,所以下面题目主要也是这些算法做的
我讲述题目会把讲解部分分为3个部分:
1、题目解析
2、算法原理思路讲解
3、代码实现
最长湍流子数组
题目链接:最长湍流子数组
题目
给定一个整数数组 arr
,返回 arr
的 最大湍流子数组的长度 。
如果比较符号在子数组中的每个相邻元素对之间翻转,则该子数组是 湍流子数组 。
更正式地来说,当 arr
的子数组 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]
。
- 当
示例 1:
输入:arr = [9,4,2,10,7,8,8,1,9] 输出:5 解释:arr[1] > arr[2] < arr[3] > arr[4] < arr[5]
示例 2:
输入:arr = [4,8,12,16] 输出:2
示例 3:
输入:arr = [100] 输出:1
提示:
1 <= arr.length <= 4 * 104
0 <= arr[i] <= 109
解法
算法原理解析
我们这题使用动态规划,我们做这类题目可以分为以下五个步骤
- 状态显示
- 状态转移方程
- 初始化(防止填表时不越界)
- 填表顺序
- 返回值
- 状态显示
dp[i] 表示: 「以 i 位置为结尾的最长湍流数组的长度」。但是,问题来了,如果状态表⽰这样定义的话,以 i 位置为结尾的最⻓湍流数组的⻓度我们没法 从之前的状态推导出来。因为我们不知道前⼀个最长湍流数组的结尾处是递增的,还是递减的。因此,我们需要状态表⽰能表示多⼀点的信息:要能让我们知道这⼀个最⻓湍流数组的结尾是「递 增」的还是「递减」的。
因此需要两个
dp
表:
- f[i] 表示:以 i 位置元素为结尾的所有子数组中,最后呈现「上升状态」下的最长湍流数组的长度;
- g[i] 表示:以 i 位置元素为结尾的所有子数组中,最后呈现「下降状态」下的最长湍流数组的长度
- 状态转移方程
对于 i 位置的元素
arr[i]
,有下⾯三种情况:
- arr[i] > arr[i - 1] :如果 i 位置的元素⽐ i - 1 位置的元素⼤,说明接下来 应该去找 i -1 位置结尾,并且 i - 1 位置元素⽐前⼀个元素⼩的序列,那就是 g[i - 1] 。更新 f[i] 位置的值: f[i] = g[i - 1] + 1 ;
- arr[i] < arr[i - 1] :如果 i 位置的元素⽐ i - 1 位置的元素⼩,说明接下来 应该去找 i - 1 位置结尾,并且 i - 1 位置元素⽐前⼀个元素大的序列,那就是 f[i - 1] 。更新 g[i] 位置的值: g[i] = f[i - 1] + 1 ;
- arr[i] == arr[i - 1] :不构成湍流数组。
- 初始化(防止填表时不越界)
所有的元素「单独」都能构成⼀个湍流数组,因此可以将
dp
表内所有元素初始化为
1
。 由于⽤到前⾯的状态,因此我们循环的时候从第⼆个位置开始即可。
- 填表顺序
根据「状态转移⽅程」易得,填表顺序为「从左往右,两个表一起填」。
- 返回值
应该返回「两个
dp
表⾥⾯的最⼤值」,我们可以在填表的时候,顺便更新⼀个最⼤值。
代码实现
class Solution {
public:
int maxTurbulenceSize(vector<int>& arr)
{
int n = arr.size();
int ans = 1; // 最⻓湍流数组的⻓度
// 状态显示 + 初始化
vector<int> f(n + 1, 1); // 以 i 为结尾,最后呈现「上升状态」下的最⻓湍流数组的⻓度
vector<int> g(n + 1, 1); // 以 i 为结尾,最后呈现「下降状态」下的最⻓湍流数组的⻓度
// 填表(从左到右,两个表一起填)
for (int i = 1; i < n; i++)
{
if (arr[i - 1] < arr[i])
{
f[i] = g[i - 1] + 1;
}
else if (arr[i - 1] > arr[i])
{
g[i] = f[i - 1] + 1;
}
ans = max(ans, max(f[i], g[i]));
}
return ans;
}
};