
本文介绍一种高效、清晰的方法,用于判断一个由 1 到 n 的整数组成的子列表是否构成严格递增且相邻的循环连续序列(如 [35,36,1] 在 n=36 下合法),并排除重复、乱序或间隔不满足条件的情况。
本文介绍一种高效、清晰的方法,用于判断一个由 1 到 n 的整数组成的子列表是否构成严格递增且相邻的循环连续序列(如 [35,36,1] 在 n=36 下合法),并排除重复、乱序或间隔不满足条件的情况。
在处理环形编号系统(如钟表刻度、棋盘坐标、模运算索引等)时,常需验证一组数字是否构成“循环连续”的序列——即它们在模 n 意义下严格按 +1 递增,且无跳变、重复或逆序。例如,当 n = 36(模拟一圈刻度)时,[35, 36, 1] 和 [36, 1, 2] 应视为合法连续序列,而 [1, 3, 4] 或 [3, 2, 1] 则不符合要求。
核心逻辑非常直观:遍历列表,对每一对相邻元素 (prev, curr),检查是否满足 curr == prev + 1,或特殊边界情况 prev == n and curr == 1(即从末尾绕回起点)。只要任一相邻对不满足该条件,立即返回 False;若全部通过,则返回 True。
以下是一个简洁、可复用的实现:
class IsConsecutiveCyclic:
def __init__(self, n):
self.n = n
def __call__(self, seq):
if not seq:
return True # 空序列视为平凡连续(可根据需求调整)
prev = seq[0]
for curr in seq[1:]:
if curr == prev + 1 or (prev == self.n and curr == 1):
prev = curr
else:
return False
return True
# 使用示例(n = 36)
foo = IsConsecutiveCyclic(36)
print(foo([1, 2, 3])) # True
print(foo([8, 9, 10])) # True
print(foo([35, 36, 1])) # True
print(foo([36, 1, 2])) # True
print(foo([1, 3, 4])) # False(跳过 2)
print(foo([15, 17, 20])) # False(非连续)
print(foo([3, 2, 1])) # False(递减,不满足 +1 规则)
✅ 关键特性说明:
- ✅ 严格单向递增:只允许 +1 增量或 n → 1 的合法绕回,拒绝任何递减、跳跃或重复;
- ✅ 线性时间复杂度 O(k):k 为输入序列长度,无需构造辅助字符串或排序;
- ✅ 健壮性:自动处理单元素序列(恒为 True)、空序列(可按需配置);
- ❌ 不支持乱序或重复:如 [1,2,3,1,2,3] 因含重复且后续未接 4,直接判 False,符合题设“唯一且全连续”要求。
⚠️ 注意事项:
- 输入序列必须仅包含 1 到 n 范围内的整数,否则行为未定义(建议前置校验);
- 该算法不检测序列是否为完整环段的子集(如 [2,3,4,5] 合法,但 [2,4,5] 不合法),它只验证相邻关系;
- 若需支持任意起始点的任意长度循环连续段(含长度为 1 或 n),本方案已完全覆盖。
综上,相比拼接双周期字符串再子串匹配的低效方式,该方法以清晰语义、最小开销和强可读性,成为判断循环连续性的推荐实践。











