2023-04-28 Daily Challenge
Today I have done leetcode's April LeetCoding Challenge with cpp.
April LeetCoding Challenge 28
Description
Similar String Groups
Two strings X and Y are similar if we can swap two letters (in different positions) of X, so that it equals Y. Also two strings X and Y are similar if they are equal.
For example, "tars" and "rats" are similar (swapping at positions 0 and 2), and "rats" and "arts" are similar, but "star" is not similar to "tars", "rats", or "arts".
Together, these form two connected groups by similarity: {"tars", "rats", "arts"} and {"star"}. Notice that "tars" and "arts" are in the same group even though they are not similar. Formally, each group is such that a word is in the group if and only if it is similar to at least one other word in the group.
We are given a list strs of strings where every string in strs is an anagram of every other string in strs. How many groups are there?
Example 1:
Input: strs = ["tars","rats","arts","star"] Output: 2
Example 2:
Input: strs = ["omv","ovm"] Output: 1
Constraints:
1 <= strs.length <= 3001 <= strs[i].length <= 300strs[i]consists of lowercase letters only.- All words in
strshave the same length and are anagrams of each other.
Solution
struct UnionSet {
vector<int> parent;
public:
UnionSet(int size): parent(size) {
for(int i = 0; i < size; ++i) {
parent[i] = i;
}
}
int find(int x) {
if(parent[x] != x) parent[x] = find(parent[x]);
return parent[x];
}
void merge(int x, int y) {
x = find(x);
y = find(y);
parent[x] = y;
}
};
class Solution {
int len;
bool isSimilar(const string &a, const string &b) {
int pos1 = -1;
int pos = 0;
while(pos < len && a[pos] == b[pos]) {
pos += 1;
}
if(pos == len) return true;
pos1 = pos;
pos += 1;
while(pos < len && a[pos] == b[pos]) {
pos += 1;
}
if(pos == len) return false;
if(a[pos1] != b[pos] || b[pos1] != a[pos]) return false;
pos += 1;
while(pos < len && a[pos] == b[pos]) {
pos += 1;
}
return pos == len;
}
public:
int numSimilarGroups(vector<string>& strs) {
UnionSet us(strs.size());
len = strs.front().length();
int answer = strs.size();
for(int i = 0; i < strs.size() - 1; ++i) {
for(int j = i + 1; j < strs.size(); ++j) {
if(isSimilar(strs[i], strs[j]) && us.find(i) != us.find(j)) {
us.merge(i, j);
answer -= 1;
}
}
}
return answer;
}
};
// Accepted
// 77/77 cases passed (30 ms)
// Your runtime beats 80.63 % of cpp submissions
// Your memory usage beats 76.83 % of cpp submissions (10.1 MB)