题目
给定字符串的一个数组,返回能够形成anagrams的所有字符串组合。
注:anagrams指的是这样两个单词,在这两个单词当中,每一个英文字母所出现的次数都是相同的(不区分大小写)。
{a b c d e f g}
(a, c, f, e)
(e, f, a, c)
解析
设计一个哈希算法,使得任意两个由相同字符组成的字符串,都能产生相同的哈希值,是这道题的考点。
对每一个字符串取哈希值,然后哈希值相同的即为anagrams。
但是实现上还会有个问题,如果通过统计字符出现的次数来产生一个字符串的哈希值(如注视代码)虽然准确,但是对与超大字符容易超时。
比较简单的方式是通过字符出现的次数来生成一个整数哈希,但是这种实现的风险是哈希冲突,即哈希值相同不见得是anagrams。
vector<string> anagrams(vector<string> &strs){
vector<string> result;
if(strs.size() == 0) return result;
map<long, vector<string>> smap;
for(int i=0; i<strs.size(); i++)
{
smap[footprint(strs[i])].push_back(strs[i]);
}
for(auto it = smap.begin(); it != smap.end(); ++it) //auto is used to declare local variable,and is purely optional
{
if(it->second.size() <= 1)
continue;
//insert(loc,start,end)在指定位置loc前插入区间[start, end)的所有元素
result.insert(result.begin(), it->second.begin(), it->second.end());
}
return result;
}
long footprint(string str)
{
int index[26];
memset(index, 0, 26*sizeof(int));//初始化一段内存为0
for(int i=0; i<str.size(); i++)
{
index[str[i]-'a']++;
}
/*
for(int i=0; i<26; i++)
{
footp.append(1, i+'a');
stringstream ss;
ss << index[i];
footp.append(ss.str());
}
*/
long footp = 0;
int feed = 7;
for(int i=0; i<26; i++)
{
footp = footp*feed + index[i];
}
return footp;
}