给定两个字符串s
和t
,编写一个函数来判断t
是否是s
的字母异位词。
注意:
- 若
s
和t
中每个字母出现的次数都相同,则称s
和t
互为字母异位词。 s
和t
仅包含小写字母。
示例:
输入:s = “anagram”, t = “nagaram”
输出:true
思路一:
要判断是否两个字符串中每个字母出现的的次数都相同,我们可以先将这两个字符串按照字母的ASCII码进行排序,若排序后这两个字符串相同,则说明符合要求。
说明一下:
- 因为排序后相同的字母挨在一起,不同字母按照ASCII码排为升序或降序,所以满足题意要求的两个字符串经过排序后一定是两个相同的字符串。
- 在排序前可以先判断这两个字符串的长度是否相同,若不相同则说明这两个字符串一定不满足要求,无需进行后续操作。
代码如下:
//排序
class Solution {
public:
bool isAnagram(string s, string t) {
if (s.size() != t.size())
return false;
sort(s.begin(), s.end());
sort(t.begin(), t.end());
return s == t;
}
};
时间复杂度: O ( N l o g N ) O(NlogN) O(NlogN) 空间复杂度: O ( N ) O(N) O(N)
思路二:
我们可以分别统计两个字符串中每个字母出现的次数,若两个字符串中每个字母出现的次数都相同则满足要求,因此我们可以借助哈希表进行解题。
说明一下:
- 因为26个小写字母的ASCII码是连续的,所以我们在选取哈希函数时最好选用直接定址法。
- 我们不需要开辟两张哈希表进行字母统计,只需要用一张哈希表统计一个字符串中每个字母出现的次数,然后遍历另一个字符串对哈希表中的字母进行抵消即可。
- 在字母抵消过程中若哈希表中某一字母出现的次数变成了负数,则这两个字符串不满足题意,因为此时说明在两个字符串中该字母出现的次数不同。
最好提前判断两个字符串的长度是否相同:
- 因为如果这两个字符串的长度不相同则说明这两个字符串一定不满足要求,无需进行后续操作。
- 进行完统计和抵消操作后,我们只能确保第一个字符串中每个字母出现的次数都大于等于第二个字符串中对应字母出现的次数,如果保证这两个字符串的长度相等,并且抵消过程中哈希表中没有出现负数的情况,则在抵消结束后我们就能断定这两个字符串是符合要求的。
- 如果我们没有保证这两个字符串的长度相等,则在进行完统计和抵消操作后我们不能断定这两个字符串一定符合要求,还需判断哈希表中每个字母出现的次数是否都已经全部被抵消成了0。
代码如下:
//哈希表
class Solution {
public:
bool isAnagram(string s, string t) {
if (s.size() != t.size()) //保证两个字符串的长度相同
return false;
vector<int> table; //哈希表
table.resize(26); //提前开辟26个位置
//1、遍历字符串s,统计s中每个字母出现的次数
for (auto& ch : s)
{
table[ch - 'a']++;
}
//2、遍历字符串t,将t和s中的字母进行抵消
for (auto& ch : t)
{
table[ch - 'a']--;
if (table[ch - 'a'] < 0) //抵消时出现了负数
return false;
}
return true; //全部抵消成功
}
};
时间复杂度: O ( N ) O(N) O(N) 空间复杂度: O ( 1 ) O(1) O(1)