1061: Lexicographically-Smallest-Equivalent-String
Medium
table of contents
This question immediately screams disjoint set union.
It basically just requires you to create a separate data structure called a disjoint set (this will be my attempt at explaining the disjoint set class).
In the optimised DisjointSet
class, there contain 2
arrays:
In this class, there also contain 2 main methods:
- find
The job of this function is to find the parent value of the disjoint set.
In it, however, contains the first optimisation: path
compression, where find
basically shrinks the
“path” to the parent using recursion, meaning future find
functions will be near constant time.
int find(int x) {
return (x == parents[x]) ? x : (parents[x] = find(parents[x]));
}
- merge/union
The job of this function is to merge two disjoint sets
First, we have to check if they are disjoint in the first case. Take
x
and y
as an example:
int xRoot = find(x);
int yRoot = find(y);
if (xRoot == yRoot) return false;
If xRoot
and yRoot
are both equal, then we
know they are already part of the same set and do not have to
merge anything.
Else, we have merging to do.
Now, the second optimisation comes in: union by size
To ensure, that the “trees” we are creating are more balanced, it makes more sense to add the less dense “tree” to the more dense “tree” as that will minimise the amount of path compression we will have to do.
// swap "xRoot" and "yRoot" if:
if (size[xRoot] < size[yRoot]) {
(xRoot, yRoot);
swap}
// add to the LARGER root
[xRoot] += sizes[yRoot];
sizes// update the root of the SMALLER root
[yRoot] = xRoot;
parentsreturn true;
code
class DisjointSet {
private:
<int> parents;
vector<int> sizes;
vectorpublic:
(int size) : parents(size), sizes(size, 1) {
DisjointSet (parents.begin(), parents.end(), 0);
iota}
int find(int x) {
return (x == parents[x]) ? x : (parents[x] = find(parents[x]));
}
bool merge(int x, int y) {
int xRoot = find(x);
int yRoot = find(y);
if (xRoot == yRoot) return false;
if (xRoot > yRoot) {
(xRoot, yRoot);
swap}
[xRoot] += sizes[yRoot];
sizes[yRoot] = xRoot;
parentsreturn true;
}
bool connected(int x, int y) {
return find(x) == find(y);
}
};
class Solution {
public:
(string s1, string s2, string baseStr) {
string smallestEquivalentString(26);
DisjointSet dsu
for (int i = 0; i < s1.size(); ++i) {
.merge(s1[i]-'a', s2[i]-'a');
dsu}
= "";
string ans for (char c : baseStr) {
+= char(dsu.find(c-'a'))+'a';
ans }
return ans;
}
};