题目描述
给定两个字符串 s 和 t,判断 t 是否是 s 的字母异位词。
字母异位词的意思是:两个字符串包含的字符种类和每个字符出现次数都完全一致,只是顺序可以不同。
思路分析
这题是非常经典的哈希计数题。
哈希常见实现有三种:
- 数组
setmap
由于题目字符范围是小写字母 a-z,可以直接用长度为 26 的数组做计数,速度更快、空间也固定。
具体步骤:
- 如果
s和t长度不同,直接返回false。 - 遍历
s,让hash[c - 'a']++。 - 遍历
t,让hash[c - 'a']--。 - 最后检查
hash是否全为0:- 只要有一个位置不为
0,说明不是异位词; - 全为
0,说明是异位词。
- 只要有一个位置不为
C++ 代码实现
class Solution {
public:
bool isAnagram(string s, string t) {
int hash[26] = {0};
if (s.size() != t.size()) // 如果s和t的长度不相同的话,不可能是异位词
return false;
for (auto c : s) {
hash[c - 'a']++;
}
for (auto c : t) {
hash[c - 'a']--;
}
for (int i = 0; i < 26; ++i) {
if (hash[i] != 0)
return false;
}
return true;
}
};
复杂度分析
- 时间复杂度:
O(n),其中n是字符串长度。 - 空间复杂度:
O(1),计数数组长度固定为26。
易错点记录
- 忘记先判断长度是否相等。
- 把字符下标写错,比如漏写
- 'a'。 - 遍历结束后没有检查数组是否全部归零。
总结
这题的关键是把“字符是否相同”转成“每个字符出现次数是否一致”。在字符范围固定时,数组哈希是最稳妥、最高效的做法。属于哈希入门必刷题,建议熟练掌握这种“先加后减再校验”的计数套路。