
本文介绍一种时间复杂度为 o(k) 的算法,用于判断给定整数子集(取自 1 到 n 的循环序列)是否按顺序严格连续(支持跨边界如 [35,36,1]),并排除重复、逆序或跳跃情况。
本文介绍一种时间复杂度为 o(k) 的算法,用于判断给定整数子集(取自 1 到 n 的循环序列)是否按顺序严格连续(支持跨边界如 [35,36,1]),并排除重复、逆序或跳跃情况。
在处理环形编号系统(如钟表刻度、模运算索引、游戏棋盘坐标等)时,常需验证一组数字是否构成“循环连续序列”——即每个元素恰好是前一个元素的后继,且当到达最大值 n 后,下一个合法值为 1。关键约束包括:唯一性、顺序性、严格递增(含循环跳转)、无间隔。
以下是一个简洁、高效且可复用的实现方案:
class ConsecutiveChecker:
def __init__(self, n):
"""
初始化循环连续性检查器。
:param n: 循环范围上限(即数字取值范围为 1..n)
"""
self.n = n
def __call__(self, seq):
"""
检查序列是否为循环连续序列。
:param seq: 非空整数列表,元素应属于 [1, n]
:return: bool,True 表示严格循环连续,否则 False
"""
if not seq:
return False
# 验证所有元素在有效范围内
if not all(1 <= x <= self.n for x in seq):
return False
# 检查重复元素(题目要求唯一)
if len(seq) != len(set(seq)):
return False
prev = seq[0]
for curr in seq[1:]:
# 合法后继:要么 curr == prev + 1,要么 prev == n 且 curr == 1
if curr == prev + 1 or (prev == self.n and curr == 1):
prev = curr
else:
return False
return True
# 使用示例(n = 36)
foo = ConsecutiveChecker(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(逆序)
print(foo([1, 2, 2])) # False(重复)
print(foo([0, 1, 2])) # False(0 超出 [1,36] 范围)核心逻辑说明:
- 逐对检查相邻元素 (prev, curr),仅当 curr == prev + 1 或 prev == n and curr == 1 时视为合法转移;
- 显式校验输入范围与唯一性,确保符合题设“唯一、全部连续”的要求;
- 时间复杂度为 O(k)(k 为子集长度),空间复杂度 O(k)(仅用于去重检查),远优于字符串拼接模板法(O(n²) 构建 + O(n·k) 查找)。
注意事项:
- 该函数不自动排序输入——顺序敏感,[1,3,2] 与 [1,2,3] 结果不同;
- 若需支持任意起始方向(如允许逆序循环如 [3,2,1] → [3,2,1] 在 n=3 下也合法),需额外定义“循环单调性”,但本题明确要求正向连续(见 foo([3,2,1]) → False);
- 实际部署时建议增加类型检查(如 isinstance(seq, (list, tuple)))和空序列防护,以提升鲁棒性。
此方案兼顾可读性、性能与健壮性,适用于竞赛编程、嵌入式状态校验及游戏逻辑开发等场景。

















