这不是标准滑动窗口适用场景,需先按用户聚合排序、定义时间阈值、构造布尔信号数组,再在valid[]上单层遍历求最长连续1段;强行在原始订单列表用双循环滑动会误判“连续”含义。

直接说结论:这不是标准滑动窗口适用场景,强行套用双循环边界微调会失效。高频用户连续下单的“黄金时间链”本质是带时间戳的离散事件序列,需先做时序对齐和业务建模,再决定是否引入滑动窗口。
先明确问题核心不是“连续子数组”
大促期间用户下单是稀疏、非等距、带时间偏移的事件流(例如:9:02:15、9:02:48、9:05:33、9:17:01),不是数组下标连续的整数序列。原始数据结构是[{user_id, order_time, amount}, ...],而非[1, 1, 0, 0, 1, 1, 1, ...]这样的二值化窗口信号。直接套用 left/right 指针在原始订单列表上滑动,会导致“连续下单”被错误理解为“列表位置连续”,完全脱离业务含义。
正确路径:三步转化,再谈窗口
必须完成以下转换,才能让滑动窗口真正起作用:
- 按用户聚合 + 时间排序:先 group by user_id,对每个用户的订单按 order_time 升序排列,得到独立的时间序列;
- 定义“连续”的业务阈值:比如“两次下单间隔 ≤ 8 分钟”即视为同一波行为链(需结合大促节奏校准,不能拍脑袋定);
- 构造可滑动的一维信号:对每个用户序列,生成时间差数组 diff[i] = order_time[i] - order_time[i−1](i≥1),再转为布尔数组 valid[i] = (diff[i] ≤ 8*60),此时“最长连续 true 段”才对应“黄金时间链长度”。这时才可用滑动窗口求最长连续 1 子数组。
真正在代码里用滑动窗口的地方
不是在原始订单表上双循环,而是在每个用户的 valid[] 布尔数组上运行标准模板:
- right 扩展:遇到 valid[right] == true,计数器 +1;
- 遇到 false:立即重置 left = right + 1,计数器清零(因为连续性已断);
- 全程只维护当前链长和历史最大值,无需 while 收缩——这是“最长连续段”,不是“最短满足段”,收缩逻辑完全不同。
避坑提醒:别被“双循环”误导
网上很多教程写“滑动窗口用两层 for/while”,那是针对和 ≥ target这类需要动态收缩的题(如 LeetCode 209)。但求“最长连续下单链”属于最长连续满足条件子段,只需单层遍历 + 状态重置,时间复杂度 O(n),且 left 指针不回退、不嵌套 while。硬加双循环不仅没提速,反而引入逻辑错误和调试成本。

















