#include <unordered_map>
class Solution {
public:
std::unordered_map<char, int> computeMap(const std::string& s) {
std::unordered_map<char, int> m;
for (const char& c: s) {
if (!m.contains(c)) m[c] = 0;
m[c]++;
}
return m;
}
bool isAnagram(const std::string& s, const std::unordered_map<char, int>& m) {
std::unordered_map<char, int> smap;
for (const char& x: s) {
if (!m.contains(x)) return false;
if (!smap.contains(x)) smap[x] = 0;
smap[x]++;
}
return (smap == m);
}
std::vector<std::vector<std::string>> groupAnagrams(
std::vector<std::string>& strs
) {
std::vector<std::vector<std::string>> sol;
if (strs.size() <= 1) {
sol.push_back(std::vector<std::string>{ strs[0] });
return sol;
}
std::vector<std::unordered_map<char, int>> partition_maps;
for (const std::string& s: strs) {
bool was_adjusted = false;
for (int i = 0; i < sol.size(); i++) {
// check if s is anagram with partition_maps[i]
if (s.length() != sol[i][0].length()) continue;
if (!isAnagram(s, partition_maps[i])) continue;
sol[i].push_back(s);
was_adjusted = true;
break;
}
if (was_adjusted) continue;
// create new partion & corresponding map
sol.push_back(std::vector<std::string>{ s });
partition_maps.push_back(computeMap(s));
}
return sol;
}
};