题目重点:题目 aabbbaac→c;先说明每轮同时消除,再按 run 扫描迭代到稳定,分析单轮与最坏复杂度。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练版每一轮同时删除所有长度≥3 的最大相同字符 run,然后重复;若面试采用逐次消除,需重新核对并列顺序。
- 输入为普通字符序列,大小写不同字符;空串合法。
解题路线
- 先按最大连续 run 扫描当前串,长度达阈值则丢弃,否则加入新串;若本轮无删除便返回。
- 每轮同时判定基于旧串,避免左侧消除影响同轮后续判定;新串跨原 run 边界可能合并,下一轮继续。
- 示例先删 bbb,剩 aaaa c,再删 aaaa,得到 c。
- 可尝试栈优化到更低时间,但需明确一轮同时与顺序处理的语义;直接把栈中达 3 的 run 立即弹出可能改变同轮结果。
手动走一遍
aabbbaac:第一轮 a a | b b b | a a | c,删 bbb 得 aaaac;第二轮删 aaaa,最终 c。若 abc 没有连续三字符,原样返回。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
def eliminate_runs(text, threshold=3):
"""Remove every run of length >= threshold simultaneously, repeat."""
if threshold <= 1:
return ""
while True:
kept = []
removed = False
i = 0
while i < len(text):
j = i + 1
while j < len(text) and text[j] == text[i]:
j += 1
if j - i >= threshold:
removed = True
else:
kept.append(text[i:j])
i = j
if not removed:
return text
text = "".join(kept)
复杂度
每轮 O(n) 扫描/空间,最多 O(n) 轮,保守时间 O(n²)、空间 O(n);消除后字符串缩短,实际可更少。
易错点与追问
容易失分的边界
- 只消第一轮,不处理拼接后新 run。
- 把‘三个以上’误作严格大于 3。
- 未确认多个 run 同时还是按扫描顺序消除。
- 声称简单栈一定 O(n) 且同语义,却未验证同时消除规则。
继续深挖
- 如何证明或实现线性时间?
- 如果每轮只消最左 run 结果是否相同?
- 输入以流式 chunk 到达怎么办?
