题目重点:给字符串返回出现次数最多的字符;明确空输入、大小写和频次并列的训练规则,避免依赖哈希表遍历顺序。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 字符按 Python 字符(Unicode code point)计数,大小写不同;若面试官要求字节/大小写合并应调整。
- 同频时返回在原字符串最先出现的字符;题目未明确 tie-break,这只是确定性训练规则。
- 空串返回 None;真实接口可能需要报错或空字符,需现场核对。
解题路线
- 第一遍用频次表计算每个字符的总出现次数。
- 第二遍按输入顺序比较频次,只有严格大于当前最好频次才更新。因而并列时自然保留最先出现的字符,不依赖字典内部顺序。
- 如果字符集已知为固定大小 ASCII,也可用固定数组计数;Unicode 泛化采用哈希表。
手动走一遍
文本 'abaca' 中 a 三次、b/c 各一次,返回 a。文本 'baba' 中 a、b 均两次,训练版返回先出现的 b;题目未明确这一并列期望。
Python 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
from collections import Counter
def most_frequent_character(text: str) -> str | None:
"""Training tie rule: earliest first appearance in the input."""
if not text:
return None
frequency = Counter(text)
best = text[0]
for char in text:
if frequency[char] > frequency[best]:
best = char
return best
if __name__ == "__main__":
assert most_frequent_character("abaca") == "a"
复杂度
字符串长 n、不同字符 d:两次扫描 O(n) 时间,计数表 O(d) 空间。固定小字符集可把空间视为 O(1)。
易错点与追问
容易失分的边界
- 用 set(text) 的无序遍历选并列者,结果不稳定。
- 把大写 A 和小写 a 自动合并而未与题意确认。
- 假定空串总有一个最高频字符。
继续深挖
- 若要返回全部并列最高频字符,如何保持首次出现次序?
- 输入为实时字符流时,如何维护当前最高频字符及并列规则?
- 如按 grapheme cluster 而非 code point 计数,需要怎样的文本切分?
