掉坑总结:
方法二中对字符串先排序,使用散列表的形式其实我一开始就想到了,但是我怀疑这样对所有字符串排序是否太耗时???(我是那样坚定的认为的),因此我才想出了方法一种那种通过下标的方式,然而现实就是我认为性能好的方法一效率远远低于我认为效率不好的方法二,也算一个警告,性能不是分析那样想当然的。
描述
给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
示例:
输入: ["eat", "tea", "tan", "ate", "nat", "bat"]
输出:
[
["ate","eat","tea"],
["nat","tan"],
["bat"]
]
说明:
所有输入均为小写字母。
不考虑答案输出的顺序。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/group-anagrams/
求解
class Solution {
public:
// 方法一,双重循环对两两字符串判断是否异位,如果是则将下标组合在一起,注意,使用了一个visited标记组合,访问过或者已经被归纳的下标不再比较
// 最后根据分组的下标重新获取字符串组合
// 低效率通过,1440ms
vector<vector<string>> groupAnagrams_1e(vector<string> &strs) {
const int n = strs.size();
vector<int> indexRec; // 下标组合
indexRec.reserve(n);
for (int i = 0; i < n; ++i) {
indexRec.emplace_back(i);
}
// 将所有字符串异构的下标放在一个集合中
vector<bool> visited(n, false); // 标识某个下标对应的字符串是否已经被识别为异构字符串
vector<vector<int>> midRes;
for (int i = 0; i < n; ++i) {
if (visited[i]) {
continue;
}
vector<int> group{i};
visited[i] = true;
for (int j = i + 1; j < n; ++j) {
if (!visited[j] && isAnagrams(strs[i], strs[j])) {
visited[j] = true;
group.emplace_back(j);
}
}
midRes.push_back(std::move(group));
}
// 最终结果处理,根据下标集合合并字符串
vector<vector<string>> res;
for (const auto &indexGroup : midRes) {
vector<string> strGroup;
for (const auto &index : indexGroup) {
strGroup.push_back(std::move(strs[index]));
}
res.push_back(std::move(strGroup));
}
return res;
}
// 方法二,对字符串排序,使用Hashmap
// 高效率通过,36ms
vector<vector<string>> groupAnagrams(vector<string> &strs) {
std::unordered_map<string, vector<string>> record;
for (const auto &str : strs) {
string key = str;
std::sort(key.begin(), key.end());
record[key].emplace_back(str);
}
vector<vector<string>> res;
for (auto &[key, strGroup] : record) {
res.emplace_back(strGroup);
}
return res;
}
private:
// 判断两个字符串是否异位
bool isAnagrams(const std::string_view lhs, const std::string_view rhs) const {
if (lhs.size() != rhs.size()) {
return false;
}
int record[26]{0};
for (const char &c : lhs) {
++record[c - 'a'];
}
for (const char &c : rhs) {
if (record[c - 'a'] <= 0) {
return false;
}
--record[c - 'a'];
}
return true;
}
};