leetcode第242题. 有效的字母异位词
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
思路
暴力解法:两层for 循环,同时还要记录字符是否重复出现,很明显时间复杂度是 O(n^2)。
哈希法:数组其实就是一个简单哈希表,而且这道题目中字符串只有小写字符,那么就可以定义一个数组,来记录字符串s里字符出现的次数。
需要定义一个多大的数组呢,定一个数组叫做record,大小为26 就可以了,初始化为0,因为字符a到字符z的ASCII也是26个连续的数值。
为了方便举例,判断一下字符串s= “aee”, t = “eae”。
操作动画如下:
定义一个数组叫做record用来上记录字符串s里字符出现的次数。
需要把字符映射到数组也就是哈希表的索引下表上,「因为字符a到字符z的ASCII是26个连续的数值,所以字符a映射为下表0,相应的字符z映射为下表25。」
再遍历字符串s的时候,「只需要将 s[i] - ‘a’ 所在的元素做+1 操作即可,并不需要记住字符a的ASCII,只要求出一个相对数值就可以了。」 这样就将字符串s中字符出现的次数,统计出来了。
那看一下如何检查字符串t中是否出现了这些字符,同样在遍历字符串t的时候,对t中出现的字符映射哈希表索引上的数值再做-1的操作。
那么最后检查一下,「record数组如果有的元素不为零0,说明字符串s和t一定是谁多了字符或者谁少了字符,return false。」
最后如果record数组所有元素都为零0,说明字符串s和t是字母异位词,return true。
时间复杂度为O(n),空间上因为定义是的一个常量大小的辅助数组,所以空间复杂度为O(1)。
c++代码
哈希法
class solution
{
public:
bool isAnagram(string s, string t)
{
int record[26] = {0};
//遍历第一个字符串,用record记录出现的字符次数
for (int i = 0; i < s.size(); i++)
{
record[s[i] - 'a']++;
}
//遍历第二个字符串,其在record中对应的字符次数递减
for (int i = 0; i < t.size(); i++)
{
record[t[i] - 'a']--;
}
//最后判断record数组中是否有非0元素,存在非0元素说明字符串s和t一定是谁多了字符或者谁少了字符,return false
for (int i = 0; i < 26; i++)
{//因为数组大小固定为26
if (record[i] != 0)
{
return false;
}
}
return true;
}
};
暴力解法
leetcode上貌似超时了。
class solution
{
public:
bool isAnAgram(string s, string t)
{
//两个字符串长度不一样直接return false
if (s.size() != t.size()) return false;
//需要一个额外的数组标识第二个字符串已匹配的字符, 大小就为第二个字符串的长度
vector<bool> used(t.size(), false);
for (int i = 0; i < s.size(); i++)
{
for (int j = 0; j < t.size(); j++)
{
if (s[i] == t[j])
{//字符匹配
if (used[j] == true)
{//字符t[j] 已匹配过了
continue;
}
used[j] = true;
break;
}
}
}
//最后判断used数组是否有没匹配的
for (int i = 0; i < used.size(); i++)
{
//如果used数组中有没匹配的,说明t中有不匹配s中的字符存在
if (used[i] == false) return false;
}
return true;
}
};