判断两个字符串是否为异位词的核心是字符组成及频次完全相同。php推荐用字符频次统计法(o(n)时间),辅以排序比对或单数组优化法,并注意utf-8、大小写、空格等边界处理。

判断两个字符串是否为异位词(Anagram),核心是:它们由**完全相同的字符组成,且每个字符出现次数一致**,只是顺序不同。PHP 中有多种高效方式实现,关键在于避免暴力排序或嵌套循环。
方法一:字符频次统计(推荐)
统计两个字符串中各字符的出现次数,比较频次数组是否完全相等。适合所有字符集(含 Unicode),时间复杂度 O(n),空间复杂度 O(k)(k 为不同字符数)。
- 使用 array_count_values() 配合 str_split() 拆分字符串(注意:UTF-8 多字节字符需用 mb_str_split(),PHP 7.4+)
- 统一转为小写(如忽略大小写),并过滤空格/标点(按需)
- 直接用 === 比较两个频次数组(键名、键值、顺序都需一致)
方法二:排序后比对(简洁适用 ASCII)
将两字符串分别拆成字符数组、排序、合并回字符串,再比较是否相等。代码短,但对 UTF-8 多字节字符需谨慎处理。
- 适用于纯英文、数字等单字节字符场景
- 用 str_split() + sort() + implode() 实现
- 若需支持中文等,改用 mb_str_split() 并配合 usort() 和 mb_strcmp()
方法三:长度预检 + 单频次数组(优化版)
先快速判断长度是否相等;再遍历第一个字符串累加频次,第二个字符串遍历减频次;最后检查频次数组是否全为 0。节省一次数组构建,内存更友好。
立即学习“PHP免费学习笔记(深入)”;
- 用 isset() 和 unset() 动态维护频次,避免冗余键
- 遇到负值可提前返回 false(第二个字符串某字符超量)
- 遍历完后检查数组是否为空 —— 是则为异位词
注意事项与边界处理
实际使用时别忽略这些细节:
- 空字符串互为异位词("" 和 ""),但 "" 和 "a" 不是
- 是否忽略空格、标点、大小写?需在预处理阶段统一清洗(如 preg_replace('/[^a-z0-9]/', '', strtolower($s)))
- Unicode 字符(如 emoji、中文)必须用 mb_* 系列函数,否则 str_split() 会切碎字节导致错误
- 超长字符串慎用排序法,频次统计更稳定











