深入 Java 滑动窗口:「最长湍流子数组」的状态判断与窗口调整
·
深入 Java 滑动窗口:「最长湍流子数组」的状态判断与窗口调整
一、问题定义与核心概念
湍流子数组指满足特定交替关系的连续子数组:若相邻元素的大小关系呈周期性变化(即满足 $arr[i] > arr[i+1] < arr[i+2] > \dots$ 或 $arr[i] < arr[i+1] > arr[i+2] < \dots$),则称为湍流子数组。例如数组 $[9,4,2,10,7,8]$ 中,子数组 $[4,2,10,7,8]$ 满足: $$4 > 2 < 10 > 7 < 8$$ 其长度为 5,是最长湍流子数组。
二、滑动窗口算法设计
核心思想:通过双指针动态维护满足湍流条件的窗口,实时调整边界以追踪最大长度。
状态判断关键点
- 相邻关系符号:定义比较函数 $cmp(a,b)$:
- $cmp(a,b) > 0$ 表示 $a > b$
- $cmp(a,b) < 0$ 表示 $a < b$
- $cmp(a,b) = 0$ 表示 $a = b$
- 交替性验证:对窗口内连续三元素 $arr[k-2], arr[k-1], arr[k]$,需满足: $$cmp(arr[k-1], arr[k-2]) \times cmp(arr[k], arr[k-1]) < 0$$ 即两次比较结果符号相反。
窗口调整策略
- 扩展条件:新元素加入后仍满足交替性,右指针 $right$ 右移。
- 收缩条件:
- 若 $arr[right] = arr[right-1]$,重置窗口起点($left = right$)
- 若连续三次比较符号相同,将左指针移至 $right-1$
三、Java 实现与注释
public int maxTurbulenceSize(int[] arr) {
int n = arr.length;
if (n <= 1) return n;
int left = 0, maxLen = 1;
for (int right = 1; right < n; right++) {
// 1. 计算当前相邻元素关系
int currCmp = Integer.compare(arr[right], arr[right-1]);
if (currCmp == 0) {
// 相等元素破坏湍流,重置窗口起点
left = right;
} else if (right >= 2) {
// 2. 计算前次相邻关系
int prevCmp = Integer.compare(arr[right-1], arr[right-2]);
// 3. 检查交替性:符号需相反
if (prevCmp * currCmp >= 0) {
left = right - 1; // 收缩窗口
}
}
// 4. 更新最大窗口长度
maxLen = Math.max(maxLen, right - left + 1);
}
return maxLen;
}
关键步骤解析
- 初始化:$left=0$, $maxLen=1$(单元素总满足条件)
- 遍历:右指针 $right$ 从 1 开始扫描数组
- 关系计算:
currCmp检测 $arr[right]$ 与 $arr[right-1]$ 关系prevCmp检测 $arr[right-1]$ 与 $arr[right-2]$ 关系(当 $right \geq 2$)
- 窗口调整:
- 出现相等元素时($currCmp=0$),窗口重置至当前位置
- 连续两次比较符号相同($prevCmp \times currCmp \geq 0$),左指针移至 $right-1$
- 长度更新:实时计算窗口长度 $right - left + 1$
四、复杂度与边界分析
- 时间复杂度:$O(n)$
仅需单次遍历数组,每个元素处理 $O(1)$ 时间。 - 空间复杂度:$O(1)$
仅使用固定数量的指针变量。 - 边界处理:
- 数组长度 $\leq 1$ 时直接返回
- 全等数组(如 $[2,2,2]$)返回 1
- 全递减/递增数组(如 $[3,2,1]$)返回 2
五、算法特性总结
- 动态适应性:窗口根据实时比较关系调整,避免重复验证历史数据。
- 符号驱动:通过比较结果的符号乘积($prevCmp \times currCmp$)高效判断交替性。
- 隐式回溯:当窗口收缩至 $[right-1, right]$ 时,保留最后两个有效元素作为新起点。
应用场景扩展:该滑动窗口模式可推广至所有需验证局部连续关系的子数组问题,如交替二进制串、波形数组等,只需修改状态判断逻辑即可适配。
本文通过拆解湍流子数组的核心特征,结合滑动窗口的状态判断与边界调整策略,实现了高效求解。代码清晰展现了窗口收缩/扩展的触发条件,为处理类似问题提供通用范式。
更多推荐
所有评论(0)