政协十三届二次会议于今天开幕,作为一名党员还是应该好好看看吧!言归正传,刚刚又刷了一道题,这道题还是有点难度的,所以参考了一下别人的解法,下面来分享一下经验吧!
Given an array of strings, group anagrams together.
Example:
Input: ["eat", "tea", "tan", "ate", "nat", "bat"],
Output:
[
["ate","eat","tea"],
["nat","tan"],
["bat"]
]
Note:
All inputs will be in lowercase.
The order of your output does not matter.
题意分析:
给定一个字符串数组(数组没有特殊指明,应该可以为空集),请寻找anagrams组,说白了就是将相同字母组成各种不同顺序的组合放一起,然后用一个二维向量组返回结果。注:①所有的输入均为小写字母;②最终返回结果的顺序不重要。
解答如下:
方法一(哈希表嵌套集合法)
根据题意,可以先把每个字符串进行排序,然后创建一个hash_map(unordered_map型变量),其
键为每个字符串排序后的结果,其值为一个set,用于存放(insert)排序前的结果。由于set的底层实现利用了平衡二叉树,所以集合元素都是按照顺序排好了的。
注:①hash_map(哈希表)是指unordered_map,对于
map的底层实现还是平衡二叉树,所以map的到的结果也是有序的。
②由于set,map底层实现是平衡二叉树,所以他们的时间复杂度为O(logn),而unordered_set,unordered_map的底层实现是hash_map,所以他们的时间复杂度为O(1)。
class Solution{
public:
vector<vector<string> > groupAnagrams( vector<string>& strs){
vector<vector<string> > result;
string tmp; //这里不可以定义为vector,因为定义的set中装的是string
unordered_map<string,multiset<string>> record;
for (int i = 0; i < strs.size(); i++) {
tmp = strs[i];
sort(strs[i].begin(),strs[i].end());
record[strs[i]].insert(tmp); //map和set的插入操作
}
for (auto rec : record) { //遍历hash map的所有元素
vector<string> res (rec.second.begin(), rec.second.end()); //用hash map中每个元素的值(字符串集合),对向量res进行初始化。
result.push_back(res);
}
return result;
}
};
提交后的结果如下:
方法二(优化方法一)
①方法一中系统自带的sort排序为改进的快排算法,时间复杂度为O(nlogn)。由于题目明确指出只有小写字母,故可以使用计数排序进一步加快算法的速度(从O(nlogn)降为O(n))。
②方法一未判断字符串数组为空集的情况。
③对方法一中两处for循环进行优化。
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> result;
if (strs.empty()) { //判断字符串数组是否为空
return result;
}
unordered_map<string, multiset<string>> record;
for (string str : strs) { //优化for循环
string tmp = countSort(str);
record[tmp].insert(str);
}
for (auto rec : record) { //优化for循环
vector<string> res(rec.second.begin(), rec.second.end());
result.push_back(res);
}
return result;
}
string countSort(string s) { //计数排序
vector<int> count(26, 0);
for (int i = 0; i < s.length(); ++i) {
++count[s[i] - 'a'];
}
string res = "";
for (int i = 0; i < 26; ++i) {
while (count[i]--) {
res += ('a' + i);
}
}
return res;
}
};
提交后的结果如下:
日积月累,与君共进,增增小结,未完待续。