最快方法是用std::sort排序后比较,但需先检查长度是否相等、对输入副本排序;字符频次数组法O(n)更高效,适用于小写字母等受限字符集。

用 std::sort 最快写对,但要注意比较对象必须是副本
异位词(anagram)本质是两个字符串含相同字符、相同频次,只是顺序不同。最直觉的做法就是排序后比对——但直接对原字符串排序会破坏输入,后续无法复用;若函数签名是 bool isAnagram(const std::string& s, const std::string& t),就必须拷贝再排。
常见错误是漏掉长度判断:长度不等直接返回 false,这是 O(1) 的快速剪枝,别跳过。
- 先检查
s.length() != t.length(),不等直接返回false - 分别构造临时副本:
std::string s1 = s, t1 = t,再调用std::sort(s1.begin(), s1.end())和std::sort(t1.begin(), t1.end()) - 最后用
s1 == t1比较,不要手写循环
用字符频次数组替代哈希表,26 个小写字母场景下更稳更快
当题目明确限定只含小写英文字母(如 LeetCode 242),用长度为 26 的 std::array<int></int> 或 int count[26] = {} 是最优解:无哈希冲突、无内存分配、缓存友好。
容易踩的坑是把字符转索引写成 c - 'a' 却没验证 c 是否真在 'a'–'z' 范围内——一旦输入含大写或符号,就会越界访问。所以务必先做范围检查,或改用 std::unordered_map<char int></char> 保底。
立即学习“C++免费学习笔记(深入)”;
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- 初始化数组全为 0:
int cnt[26] = {}(C++ 中带= {}才能零初始化) - 遍历
s:对每个c执行cnt[c - 'a']++;遍历t则执行cnt[c - 'a']-- - 最后用
std::all_of(cnt, cnt + 26, [](int x) { return x == 0; })检查是否全零
std::unordered_map 通用但要注意键类型和清空时机
处理任意 Unicode 字符、数字、符号混合的字符串时,std::unordered_map<char int></char> 是安全选择。但它比数组慢约 3–5 倍(哈希计算 + 内存分配),且默认构造的 map 不自动清零——如果复用同一个 map 变量检测多组字符串,必须显式调用 map.clear(),否则残留计数会导致误判。
另一个坑是误用 map[c]++ 在未初始化时触发隐式插入:对不存在的键 c,map[c] 会构造 int()(即 0),再自增为 1。这本身没错,但若你之后想遍历所有键做校验,得用 map.size() 而非硬编码 26。
- 声明放在函数内(避免静态变量残留状态):
std::unordered_map<char int> freq;</char> - 遍历
s时用freq[c]++;遍历t时用freq[c]-- - 检查时别只看值:用
std::all_of(freq.begin(), freq.end(), [](const auto& p) { return p.second == 0; }),并确认freq.size()与预期一致(可选)
滑动窗口法适用于子串异位词查找,不是两字符串比对
看到“异位词”就条件反射写滑动窗口?那是针对「在长字符串 s 中找是否存在 t 的异位词作为子串」这类题(如 LeetCode 438)。它和两字符串是否互为异位词是不同问题:前者要 O(n) 时间扫一遍,后者只需 O(1) 或 O(k log k)。
如果题目只要求判断两个完整字符串是否互为异位词,硬套滑动窗口反而引入冗余逻辑:建窗口、维护左右边界、频繁更新频次——代码变长、易出错、性能不增反降。确认题干说的是“两个字符串”还是“一个字符串中是否包含另一个的异位词子串”,再决定用不用窗口。
真正关键的是:字符集是否受限、输入是否可信、是否需复用中间结果。这些比“用什么算法”更能决定最终实现的健壮性。

















