LeetCode49-字母异位词分组
给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
示例:
输入: ["eat", "tea", "tan", "ate", "nat", "bat"],
输出:
[
["ate","eat","tea"],
["nat","tan"],
["bat"]
]
说明:
所有输入均为小写字母。
不考虑答案输出的顺序。
一、思路
(一)直接方法
设置一个map向量,专门用来统计字符串中,所有字符出现的频率,比较一下即可
这个方法在实现过程中遇到了不少问题,一个是时间复杂度太高,所以我使用快速排序,按照字符串长度从小到大进行排序,如此一来可以大幅减少时间
C++代码:
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
map<char, int> hash_char;
map<char, int> hash_char2;
vector<vector<string>> ans;
vector<string> temp;
if (strs.empty())
return ans;
sort_str_len(strs, 0, strs.size() - 1);
while (strs.size()) {
temp.push_back(strs[0]);
strs.erase(strs.begin(), strs.begin() + 1);
if (temp[0].size() != strs[0].size()) {
ans.push_back(temp);
temp.clear();
continue;
}
// 获取匹配字符串信息
for (int j = 0; j < temp[0].size(); j++) {
if (hash_char.count(temp[0][j]))
hash_char[temp[0][j]]++;
else
hash_char.insert(map<char, int>::value_type(temp[0][j], 1));
}
// 开始匹配
for (int i = 0; i < strs.size(); i++) {
hash_char2 = hash_char;
if (strs[i].size() != temp[0].size())
break;
for (int j = 0; j < strs[i].size(); j++) {
if (hash_char2.count(strs[i][j]))
hash_char2[strs[i][j]]--;
else
break;
if (hash_char2[strs[i][j]] == 0)
hash_char2.erase(strs[i][j]);
}
if (hash_char2.empty()){
temp.push_back(strs[i]);
strs.erase(strs.begin() + i, strs.begin() + i + 1);
i--;
}
}
ans.push_back(temp);
temp.clear();
hash_char.clear();
hash_char2.clear();
}
return ans;
}
// 下面两个函数都是快排算法
void sort_str_len(vector<string>& strs, int begin, int end) {
if (begin >= end)
return;
int q;
q = partition_len(strs, begin, end);
sort_str_len(strs, begin, q - 1);
sort_str_len(strs, q + 1, end);
}
int partition_len(vector<string>& strs, int p1, int p2) {
int i = p1 - 1;
// 选定:基准
string x = strs[p2], s;
for (int j = p1; j < p2; j++) {
if (strs[j].size() <= x.size()) {
s = strs[j];
strs[j] = strs[i + 1];
strs[i + 1] = s;
i = i + 1;
}
}
s = strs[p2];
strs[p2] = strs[i + 1];
strs[i + 1] = s;
i = i + 1;
return i;
}
};
执行效率:
太慢了。看来要换一种方法。
(二)字符串排序
如果两个字符串仅仅是排序不同,那么可以通过sort函数,使得字符串按照字母的ASCII大小升序排序,重新排列,这样就很容易的判断两个字符串是否为字母异位词了。
C++代码:
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> ans;
map<string, vector<string>> hash_t;
string s;
for (string str : strs) {
s = str;
sort(s.begin(), s.end());
hash_t[s].push_back(str);
}
for (auto temp : hash_t)
ans.push_back(temp.second);
return ans;
}
};
执行效率