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 <= 300
1 <= strs[i].length <= 300
strs[i]
consists of lowercase letters only.- All words in
strs
have 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)