题目
最长湍流子数组
当 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])
示例 2:
输入:[4,8,12,16]
输出:2
示例 3:
输入:[100]
输出:1
提示:
1 <= A.length <= 40000
0 <= A[i] <= 10^9
解题
分析:
很明显这里就有两个状态,数组上升与下降的两个需要考虑的主要状态以及相等这个断点状态
。
所以我们要做的时在以下情况重置长度:
1.相等
2.连续上升
3.连续下降
实现起来不难,使用数据结构算法设计里的动态规划。
上升状态记为u,下降记为d,返回计数设为count
因为就算只有一个元素其初始长度也有1,所以赋值1.
int maxTurbulenceSize(int* arr, int arrSize) {
int count = 1;
int d = 1, u = 1;
然后对数组进行遍历
for (int i = 1; i < arrSize; i++) {
}
前面说到下降与上升交替才能进行增加,同时又要使得连续执行上升或者下降之后重置。
所以可以通过变量的赋值交换来实现状态转换,初值相等,当下降时就会作为初次湍流子数组加一,长度为2,在下一次如果是上升要在词基础上加一变成长度3,但是上升元素没变,所以应该基于下降计数加一,就是
if (arr[i - 1] < arr[i]) {
u = d + 1;
}
同理下降也需要从上升计数里加
if (arr[i - 1] > arr[i]) {
d = u + 1;
}
状态转换这样依然不行,因为这样不能限制住连续宿舍或者下降,我们需要在上升之后再次上升会让数目重置变为2,因为上次执行的是==u = d + 1;==想要使得下次执行或者更多次连续都保持为2,就需要每次上升对d重新赋值,重置为1;
if (arr[i - 1] < arr[i]) {
u = d + 1;
d = 1;
}
同理下降也是
if (arr[i - 1] > arr[i]) {
d = u + 1;
u = 1;
}
除去连续增减还有保持不变,这种情况对于两个都需要进行重置,所以就有以下逻辑:
else {
d = 1;
u = 1;
}
这样还没有完,我们这时候得到的是u和d,我们需要把这两个转换为计数count,所以在每次进行转换后需要选取两者之间的较大的值为最后的湍流子数组长度。
count = fmax(count, d);
count = fmax(count, u);
综合以上逻辑可以得到完整代码:
int maxTurbulenceSize(int* arr, int arrSize) {
int count = 1;
int d = 1, u = 1;
for (int i = 1; i < arrSize; i++) {
if (arr[i - 1] > arr[i]) {
d = u + 1;
u = 1;
} else if (arr[i - 1] < arr[i]) {
u = d + 1;
d = 1;
} else {
d = 1;
u = 1;
}
count = fmax(count, d);
count = fmax(count, u);
}
return count;
}
可以在以下程序直接运行测试:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int maxTurbulenceSize(int* arr, int arrSize);
int main()
{
int arr[12]={9,4,2,10,7,8,8,1,9,19,323,11,};
int a=maxTurbulenceSize(arr,12);
printf("最长湍流数组大小为%d\n",a);
}
int maxTurbulenceSize(int* arr, int arrSize) {
int count = 1;
int d = 1, u = 1;
for (int i = 1; i < arrSize; i++) {
if (arr[i - 1] > arr[i]) {
d = u + 1;
u = 1;
} else if (arr[i - 1] < arr[i]) {
u = d + 1;
d = 1;
} else {
d = 1;
u = 1;
}
count = fmax(count, d);
count = fmax(count, u);
}
return count;
}
加油!