
本文详解如何高效识别输入整数序列中是否存在长度至少为 n、公差为 r 的连续等差子序列,并在找到时输出前 n 个元素;核心在于动态维护当前潜在等差段,及时清空中断序列,避免重复/错位累积。
本文详解如何高效识别输入整数序列中是否存在长度至少为 n、公差为 r 的连续等差子序列,并在找到时输出前 n 个元素;核心在于动态维护当前潜在等差段,及时清空中断序列,避免重复/错位累积。
要解决“检测指定步长与最小长度的连续等差子序列”这一问题,关键在于在线扫描 + 滑动窗口式状态维护:我们不预存整个序列(可能很长),而是在逐个读入数字的过程中,实时判断当前是否正处于一个有效的等差进展中。
核心思路:用列表 nl 动态维护当前连续等差段
-
nl并非存储所有历史值,而是仅保存当前正在延伸的、以r为公差的连续子序列的元素。 - 每读入一个新数
curr:- 若
curr - nl[-1] == r,说明它能延续当前等差段 → 直接追加curr; - 否则,当前等差链已断裂 → 清空
nl,并以curr作为新等差段的起点(即nl = [curr])。
- 若
- 注意:初始时需先读一个数设为起点,因此
nl初始化为[curr],再进入循环处理后续数字。
正确实现要点解析
-
避免状态污染:原代码未重置
count和nl,导致断裂后仍累积旧值,输出非连续元素。修正后使用nl.clear()确保每次只跟踪当前有效段。 -
无需去重与排序:因为
nl始终维护严格连续、顺序正确的子序列,直接print(*nl)即可输出前n个原始位置元素。 -
提前终止优化:一旦
len(nl) == n,立即print并break,不再消耗后续输入——这对大数据流或交互式输入至关重要。 -
利用
while-else简洁处理失败情况:else子句仅在循环自然结束(无break)时执行,完美对应“未找到”的语义。
完整可运行代码(基于 yogi.scan)
from yogi import scan
n = scan(int)
r = scan(int)
curr = scan(int)
nl = [curr] # 初始化:首个元素构成长度为1的候选段
while curr is not None:
# 检查 curr 是否能延续当前等差段(需满足 curr == nl[-1] + r)
if len(nl) > 1 and curr - nl[-1] != r:
nl.clear() # 中断!清空旧段
nl.append(curr) # 无论是否延续,curr 总是新段的最新元素(或新段起点)
if len(nl) == n:
print(*nl)
break
curr = scan(int)
else:
print(f"No arithmetic progression found with step {r} and length at least {n}")✅ 注意:
if len(nl) > 1 and ...条件确保首次追加(nl=[first]后curr第二次读入)不会误判——因为此时nl只有 1 个元素,尚无前驱可比,直接追加即开始构建新段。
常见误区警示
- ❌ 错误地在每次匹配时同时添加
prev和curr→ 导致重复、顺序错乱、无法反映真实连续性; - ❌ 忽略
clear()导致nl越积越多,最终输出跨断裂点的“伪等差”序列; - ❌ 使用
sorted(set(...))掩盖逻辑缺陷 → 违背“连续子序列”题干要求,且破坏原始顺序; - ❌ 未
break导致程序继续读取无关数据,可能引发输入错位或超时。
该方案时间复杂度为 O(L)(L 为序列总长度),空间复杂度仅为 O(n),兼具正确性、效率与可读性,是处理此类流式等差检测问题的标准范式。

















