
本教程介绍一种无需存储全部输入的优化解法:仅通过记录前一个磁铁状态,逐行读取并实时判断分组变化,将空间复杂度从 o(n) 降至 o(1),代码更简短、逻辑更清晰。
本教程介绍一种无需存储全部输入的优化解法:仅通过记录前一个磁铁状态,逐行读取并实时判断分组变化,将空间复杂度从 o(n) 降至 o(1),代码更简短、逻辑更清晰。
在“磁铁分组”问题中,每块磁铁以字符串形式给出(仅可能是 "01" 或 "10"),表示其南北极朝向。当相邻磁铁极性相异(即字符串不同)时,它们无法连接,从而形成新的独立组;若相同,则可首尾相连,属于同一组。因此,最终组数等于相邻磁铁状态发生变化的次数 + 1(至少存在一组)。
原始解法使用 list 存储全部 n 个磁铁,并借助 itertools.tee 实现成对遍历,虽功能正确,但存在明显冗余:
- 时间上:多一次遍历构造列表;
- 空间上:需 O(n) 内存存储所有输入,对大规模输入(如 n = 10⁶)不友好;
- 可读性上:pairwise 辅助函数和迭代器操作增加了理解成本。
✅ 优化核心思想:
磁铁分组仅取决于当前磁铁与前一块是否相同。我们完全不需要记住历史所有值,只需维护一个变量 prev 记录上一块磁铁的状态,并在每次读入新磁铁时做一次比较即可。
以下是推荐的简洁高效实现:
n = int(input())
groups = 0
prev = None
for _ in range(n):
magnet = input().strip()
if magnet != prev:
groups += 1
prev = magnet
print(groups)
? 关键说明:
- 初始化 prev = None,确保第一个磁铁必然触发 groups += 1(因为 magnet != None 恒为 True),自然满足“至少一组”的前提;
- 使用 strip() 防止因输入末尾空格或换行符导致误判;
- 循环中无多余变量或数据结构,空间复杂度稳定为 O(1);
- 时间复杂度仍为 O(n),但常数更小,且 I/O 与逻辑完全线性流水执行。
⚠️ 注意事项:
- 输入保证仅含 "01" 或 "10",无需额外校验;若实际场景需健壮性,可添加 assert magnet in ("01", "10");
- 不要将 groups 初始化为 1 后再循环判断——那样需特殊处理 n == 0 边界,而当前写法天然兼容 n = 0(输出 0),逻辑更统一。
该解法不仅更省内存、更易理解,也更符合流式处理思想:数据“来即处理,用完即弃”,是算法优化中“空间换时间”反向实践的典型范例。











