题目来源
题目描述
class Solution{
public:
int maxTurbulenceSize(vector<int>& arr) {
}
};
题目解析
分析题意
- 我们可以把A[i + 1] > A[i]称为“上升段”,把A[i + 1] < A[i]叫做“下降段”,A[i+1] == A[i] 的称为“水平段”。
- 那么,我们要找到是一断交替上升下降的子数组,比如示例输入 [9,4,2,10,7,8,8,1,9]:
- 我们要找的就是这种上升和下降交替的波形子数组,也也是题目叫“湍流”(turbulent)子数组的原因。
- 这题应该算是376. 摆动序列的变形,只不过此题要求连续
- 我们可以发现,波形数组有一个很明显的递推关系:我们在已有的波形子数组上,再加一段上升或者下降段,就可以得到更长的波形子数组。这样一个递推关系提示我们可以用动态规划的方法来解这道题。
递推规划
(1)状态定义:
- up[i]:表示以位置
i
结尾的,并且arr[i - 1] < arr[i]
的最长湍流子数组长度 down[i]
:表示以位置i
结尾的,并且arr[i - 1] > arr[i]
的最长湍流子数组长度
up[i]和down[i]初始化都是1,因为每个数字本身就是一个小的湍流子数组
(2)状态转移方程
- 当arr[i - 1] < arr[i]时,up[i] = down[i - 1] + 1
- 当arr[i - 1] > arr[i]时,down[i] = up[i - 1] + 1
解释:湍流子数组的增长和降低是交替的动画在这里
class Solution{
public:
int maxTurbulenceSize(vector<int>& arr) {
int res = 1, n = arr.size();
std::vector<int> down(n, 1), up(n, 1);
for (int i = 1; i < n; ++i) {
if(arr[i - 1] > arr[i]){
down[i] = up[i - 1] + 1;
}else if(arr[i - 1] < arr[i]){
up[i] = down[i - 1] + 1;
}
res = std::max(res, std::max(down[i], up[i]));
}
return res;
}
};
空间优化
class Solution{
public:
int maxTurbulenceSize(vector<int>& arr) {
int res = 1, n = arr.size(), up = 1, down = 1;
for (int i = 1; i < n; ++i) {
if (arr[i] < arr[i - 1]) {
down = up + 1;
up = 1;
} else if (arr[i] > arr[i - 1]) {
up = down + 1;
down = 1;
} else {
up = 1; // 重要
down = 1;
}
res = max(res, max(up, down));
}
return res;
}
};
类似题目
题目 | 思路 |
---|---|
leetcode:53. 子数组最大累加和 maximum-subarray | |
leetcode:978. 最长湍流子数组 Longest Turbulent Subarray | |
leetcode:376. 摆动序列最长子序列长度 wiggle-subsequence |