题意:给定若干字符串,将其分组,返回组数和最大组的大小;
分组定义:两个字符串字符集相同或只差一个字符时,可将其分为一组;
传送门
输入:words = [“a”,“b”,“ab”,“cde”]
输出:[2,3]
解释:
-words[0] 可以得到 words[1] (将 ‘a’ 替换为 ‘b’)和 words[2] (添加 ‘b’)。所以 words[0] 与 words[1] 和 words[2] 关联。
-words[1] 可以得到 words[0] (将 ‘b’ 替换为 ‘a’)和 words[2] (添加 ‘a’)。所以 words[1] 与 words[0] 和 words[2] 关联。
-words[2] 可以得到 words[0] (删去 ‘b’)和 words[1] (删去 ‘a’)。所以 words[2] 与 words[0] 和 words[1] 关联。
-words[3] 与 words 中其他字符串都不关联。
所以,words 可以分成 2 个组 [“a”,“b”,“ab”] 和 [“cde”] 。最大的组大小为 3 。
题解:BFS
vector<int> groupStrings(vector<string>& words) {
unordered_map<int, int> wordmasks;
for (const string& word: words) {
int mask = 0;
for (char ch: word)
mask |= (1<<(ch-'a'));
++wordmasks[mask];
}
auto get = [](int mask) {
vector<int> ret;
for (int i = 0; i < 26; ++i)
ret.push_back(mask^(1<<i));
for (int i = 0; i < 26; ++i) {
if (mask&(1<<i)) {
for (int j = 0; j < 26; ++j) {
if (!(mask&(1<<j)))
ret.push_back(mask^(1<<i)^(1<<j));
}
}
}
return ret;
};
unordered_set<int> used;
int maxn = 0, cnt = 0;
for (const auto& [mask, occ]: wordmasks) {
if (used.count(mask))
continue;
queue<int> q;
q.push(mask);
used.insert(mask);
int total = occ;
while (!q.empty()) {
int u = q.front();
q.pop();
for (int v: get(u)) {
if (wordmasks.count(v) && !used.count(v)) {
q.push(v);
used.insert(v);
total += wordmasks[v];
}
}
}
maxn = max(maxn, total);
++cnt;
}
return {cnt, maxn};
}